来自非成员函数的C ++ Virtual Inheritance

时间:2013-07-31 15:06:16

标签: c++ inheritance virtual dynamic-cast

来自Java / 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)。

非常感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

  

A(int x):x(x){}做什么:x(x){}做什么?

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

  

B(int x):A(2 * x)

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

答案 1 :(得分: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;
       }
       //...
    };

答案 2 :(得分:1)

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

  

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

2) A(int y) : x(y) {}初始化A::x()之前的成员,其值为"()",即y(修改后的变量名称以便更好地理解。与B(int x) : A(2*x), x(x) {}一样的情况。它使用参数A调用基类(2*x)构造函数,然后用B::x初始化() x内的值,即g()

3)此外,dynamic_cast<>无效,因为 dynamic_cast<>会抛出编译错误,因为正在投放的对象需要至少有1个虚拟功能。如果唯一的虚函数是析构函数,则{{1}}将起作用。

答案 3 :(得分:0)

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

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