使用派生类初始化成员类

时间:2018-05-22 19:49:25

标签: c++ inheritance

所以我试图找到将成员类构建到派生类的最佳实践方法。

struct A {
    int a = 0
}

struct B : struct A {
    int b = 0;
}
class ContainingClassA {
    ContainingClassA() : member_A(){}

    virtual A get() {
        return member_A;
    }

    A member_A;
}

class ContainingClassB : public ContainingClassA {
    ContainingClassB(){}

    virtual B get() override{
        return member_A;
    }
}

有没有办法在类member_A中初始化ContainingClassB,使其类型为B?我已经看到可能会向ContainingClassA添加一个构造函数以初始化member_A。我知道我可以在B member_B中声明一个ContainingClassB变量并将其返回,但由于B派生自A,我似乎能以某种方式将其存储在继承的变量中member_A ...

2 个答案:

答案 0 :(得分:2)

  

有没有办法在类member_A中初始化ContainingClassB,使其类型为B?

没有。 member_AContainingClassA的成员。 ContainingClassB使用其父类member_A中的相同 ContainingClassA。您无法更改父类的布局。

此外,您无法更改虚拟功能的声明(除了少数例外)。换句话说,您无法使用A get()覆盖B get()

您可以更改get()以返回引用,然后可以使用A& get()覆盖B& get()(作为A&并且B&是协变类型。)

但首先你需要将解决方案分成一个“接口”和A和B的两个“实现”:

#include <iostream>

struct A {
    int a = 0;
};

struct B : public A {
    int b = 1;
};

class ContainingClassBase {
public:
    virtual const A& get() = 0;
};

class ContainingClassA : public ContainingClassBase {
    A member_A;
public:
    virtual const A& get() override { return member_A; }
};

class ContainingClassB : public ContainingClassBase {
    B member_B;
public:
    virtual const B& get() override { return member_B; }
};

int main() {
    ContainingClassA a;
    ContainingClassB b;
    std::cout << a.get().a << std::endl;
    std::cout << b.get().b << std::endl;
}

另请注意,分别分配A并存储指针的解决方案效率不高,因为在构造A时很难避免分配伪ContainingClassB(构造函数)仍将首先调用ContainingClassA。)

答案 1 :(得分:-1)

您可以使用模板来选择变量的类型。像这样:

#include <iostream>

struct A {
  int a = 0;
};

struct B : A
{
  int b = 0;
};

template<typename T>
class ContainingClassA
{
 public:
  ContainingClassA() : member_A(){}

  virtual T get() {
    return member_A;
  }

  T member_A;
};

class ContainingClassB : public ContainingClassA<B>
{
 public:
  ContainingClassB() { }

  virtual B get() override
  {
    return member_A;
  }
};

int main()
{
  ContainingClassB cb;
  std::cout << cb.get().a;
  std::cout << std::endl;
  std::cout << cb.get().b;
  return 0;
}