2013-07-31 159 views
0

从Java/C#背景的虚拟继承,需要一点帮助了解正在发生的事情在这里C++ ...C++从非成员函数

class A { 
    int x; 
    public: 
    A(int x) : x(x){} 

    void f(int y) { 
    cout << x + y << endl; 
    } 
}; 

class B : virtual A { 
    int x; 
    public: 
    B(int x) : A(2*x), x(x) {} 
    virtual void f(int y){ 
     cout << x + 2*y << endl; 
    } 
}; 

void h(){ 
    B b(5); 
    A &a = dynamic_cast<A &>(b); 
    a.f(10); 
    b.f 
} 

void g() { 
    A *a = this; 
    a->f(10); 
    B *b = dynamic_cast<B *>(a); 
    b->f(10); 
} 

调用H()是确定的,但调用g()将不起作用。有人能解释为什么吗?此外,在行A(int x):x(x){}什么:x(x){}呢?对于B(int x)同样的问题:A(2 * x),x(x)和:A(2 * x),x(x)。

非常感谢您的帮助。

+0

你不能在非成员函数中使用'this'。你的'dynamic_cast'将失败,因为'a'不指向'B'对象。 – juanchopanza

+2

你期望''this'在'g()'中引用了什么?至于你的第二个问题,那个构造被称为“成员初始化列表”,并且在构造对象成员时用于提供参数。 – Mankarse

+4

你真的需要解决这个问题。建立一个小的,可编辑的例子,练习你的关注,然后问。 –

回答

2

A(INT X):X(X){}什么呢:X(X){}做?

: x(x)是初始值设定项列表。 palenthesis中的变量是接收到的参数,而外部变量是成员变量。这意味着成员变量x用接收到的参数值x初始化。

B(INT X):A(2 * X)

在这里,你呼叫的基类的构造(即,A),其接收一个整数。 x是构造函数B收到的变量。这是从派生类构造函数调用参数化基类构造函数的一种方法。默认情况下,派生类构造函数调用默认的基类构造函数。在你的情况下,如果你没有提供A(2*x)它会失败,因为基类没有默认的构造函数。

+0

感谢您的回复。我的印象是编译器会生成一个默认的构造函数,如果没有提供?在这种情况下这不是真的吗? [来源](https://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr376.htm) –

+1

如果你**创建一个自定义构造函数**,编译器**不会生成**默认构造函数。 –

0

g是文件范围的函数,也就是说它不属于任何类。因此,您不能使用this

: x(x) -style表达式是成员构造函数 - 它们初始化(即调用构造函数)类的成员。

1

g()只是一个免费的功能,不是一个类的成员,所以this没有意义。我不完全相信你想在那里做

至于什么:

A(int x): x(x) 

A类有int x作为成员。这将调用该整数的构造函数,并将值x传递给构造函数A。在我看来,这是不好的风格,你应该区分两者。例如

class A { 
    int x; 
    public: 
    A(int x_in) : x(x_in){} 

    //... 
}; 

这相当于

class A { 
     int x; 
     public: 
     A(int x_in) { 
      x = x_in; 
     } 
     //... 
    }; 
+0

是的,我意识到这没有意义。我没有写这个,这是一个考试的问题。我认为一个可怜的人。所以:A(2 * x),x(x)会调用A的x和B的x?仍然对此感到困惑。 –

+0

'A :: x'将是2 * x **(传递的x)**,'B :: x'将是传递的x的值。 –

1

1)根据MSDN(回复您的问题与g()相关);

指针是仅在一个类,结构,或联合类型的非静态成员函数的指针访问。它指向调用成员函数的对象。静态成员函数没有这个指针。

2)A(int y) : x(y) {}初始化A::x()与内部的值之前该成员的"()"y(修饰的可变名称以便更好地理解)。同样是这样,与B(int x) : A(2*x), x(x) {}。它调用基类的( A)构造与参数然后初始化B::x()内的值,即x

3)铝所以,g()将无法​​正常工作,因为dynamic_cast<>会引发编译错误,因为正在传输的对象需要至少有1个虚函数。如果唯一的虚函数是析构函数,那么dynamic_cast<>就可以工作。

+0

好的,所以任何虚拟成员函数都会使A变形?这与纯粹的虚拟方法不同,它会使所有的A虚拟?是对的吗?谢谢,第一次使用C++。 –

+0

在'A'中有一个纯虚拟成员方法(我假设你的意思是“成员”)将有助于“(因为它是虚拟的),但是你不能实例化任何'A'类型的对象**,因为那纯粹的虚拟功能。 –

+0

也许这将有助于http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained –