C++继承和类成员

问题描述:

我有一个基类,从该基类派生的类,以及从派生类派生的另一个类。我的问题来自于使用构造函数来确定如何构建下一个类。C++继承和类成员

这里是使用继承时遇到的问题的简化版本。我是新来的C++。

基类:

class Grandfather 
{ 
    public: 
     Grandfather(int A, int B, int C) : a(A), b(B), c(C) 
     {} 

     virtual ~Grandfather(); 
     virtual int getA(); 
     virtual int getB(); 
     virtual int getC(); 

    private: 
     int a,b,c; 

}; 

派生父类:

class Father : public Grandfather 
{ 
    public: 
     Father(int d); 
     virtual ~Father(); 
    private: 
     int c; // i know this at compile time. How to define? 

}; 

其中Father.cpp,构造的定义如下:

Father::Father(int d){ 
    int a,b; //Father takes a parameter that then determines what a and b are 

    switch(d){ 
     case 1: 
      a=2; 
      b=5 
     case 2: 
      a=6; 
      b=9; 
     default: 
      a=10; 
      b=2; 
    } 


    Grandfather(a,b,c); // where c is a known constant for this class 
} 

和派生,派生子类:

class Child : public Father 
{ 
    public: 
     Child() : Father(int d) // d is a known constant for this class 
     {} 
     virtual ~Child(); 
    private: 
     int d; // how do i define d, if it is known at compile time? 

}; 

因此,Child在编译时具有已知的整数值。当创建一个Child对象时,它会自动调用带有其变量的构造函数Father。构造函数Father(in d)查看从Child传入的变量,进行快速操作,然后调用已知的int c的GrandFather构造函数和根据给出的int d创建的另外两个int a,b。这显然是不行的,因为默认Grandfather()构造函数自动调用

+2

'enum {d = X};'在代码注释中回答您的问题。 – kfsone

+0

相反,模板参数,可选'静态constexpr int'成员。如果OP想用传递给构造函数的参数初始化它,太糟糕了,只能是'const int'。 – LogicStuff

+0

修正'Child'构造函数中的错别字。 – LogicStuff

这显然是行不通的,因为默认的祖父()构造函数会被自动调用

良好的渔获物,并Grandfather(a,b,c);创建一个单独的临时实例。

你可以做什么:

Father::Father(int d) : 
Grandfather(determine_a(d), determine_b(d), c) // c is static constexpr 
{ 
} 

这可能是两个功能,或者您也可以使用std::array和一个determine_ab功能重构它。这是你的选择。

+0

不错,这些确定函数可以成为父类的成员吗? –

+1

他们可能是非会员或“父亲”的“私人”“静态”或“祖父”的“受保护”静态功能。 – LogicStuff

如果您不需要Father类中的int c值,并且您在编译时知道它,只需在对Grandfather的构造函数的调用中对其进行硬编码即可。与Child类中的int d值相同。要在调用Grandfather的构造函数之前确定AB的值,我认为LogicStuff具有正确和最漂亮的答案。我给你写了一个简短的例子,我简化了原始代码,并且使用了TS代码中最相关的部分。随意添加其余的。

class Grandfather 
{ 
     public: 
       Grandfather (int A, int B, int C) : a (A), b (B), c (C) { } 
     private: 
       int a, b, c; 
}; 

class Father : public Grandfather 
{ 
     public: 
       Father (const int d) : Grandfather (determine_a (d), determine_b (d), 4) { } 
       int determine_a (const int); 
       int determine_b (const int); 
}; 

class Child : public Father 
{ 
     public: 
       Child () : Father (3) { } 
}; 

int Father::determine_a (const int d) 
{ 
     if  (d == 1)  { return 2; } 
     else if (d == 2)  { return 6; } 
     else     { return 10; } 
} 

int Father::determine_b (const int d) 
{ 
     if  (d == 1)  { return 5; } 
     else if (d == 2)  { return 9; } 
     else     { return 2; } 
} 
+0

谢谢你的重写。此外,你格式化这些if语句的方式看起来很漂亮!比方说,在编译时,我们有一个已知的对象,而不是在编译时已知的int。我能否在没有错误的情况下硬编码对象在祖父的构造函数中的实例化? –

+1

自从我上次写C++以来已经有六个月了,所以我有点生疏了。但我已经纠正了我的例子中的错误。我不太清楚你在问什么,但是你不能硬编码一个对象的实例。您需要该对象的地址,并且在编写代码时不知道该对象的地址。 – BufferOverflow