【问题标题】:Override a data member in a C++ derived class覆盖 C++ 派生类中的数据成员
【发布时间】:2014-05-10 11:49:28
【问题描述】:

我对 C++ 重新定义有疑问。我在派生类中分配内存,所以我需要在基类中保留这个内存。因此,我需要考虑 Base 类中的属性与 Derived 类中的属性相同,我不知道这在 C++ 中是否可行。

class Base {
 protected:
  float * a;
  Base() {}
 public:
  virtual void reset() {
    a = 0;
  }  
  virtual void exec() {
    printf("Memory a: %x\n",a);
  }
};  

class Derivada: virtual public Base {
 protected:
  float * a;
  Derivada() {}
  virtual void reset() {
    a = new float[256];
  }
};

int main() {
  Derivada *hija= new Derivada();    
  hija->reset();
  hija->exec();
  delete hija;
}

我真的需要重载,因为这是我真正问题的一个例子。对于 CVS 的两个不同的类 Base,我的两个分支中的每个分支一个,我有相同的测试(派生一个主代码)。

在这个类Base中,我有这个属性,而在另一个类Base中,我没有这个属性,所以我必须把它放在Derived类中进行编译。

我不想制作两个不同的测试代码,所以我需要覆盖属性

【问题讨论】:

  • 只需要在基类中声明变量即可。派生类应该使用基类的变量。
  • 你真的应该在Base 中加入std::vector<float>,然后在Derived::reset() 中加入resize(256),如果这对你有用的话。每个班级不需要两个float* a。目前,您没有在Base 中将a 设置为nullptr,也没有使用复制构造函数、赋值或析构函数来管理a 的生命周期:内存总是泄漏的。 vector 会更简单、更安全。指针的printf() 格式为%p。
  • 我真的需要做阴影,因为这是我真正问题的一个例子。对于两个不同的类 Base,在 cvs 的两个不同分支中,我有相同的测试(派生一个主代码)。在一个 Base 类中,我有这个属性,而在另一个类 Base 中我没有这个属性,所以我必须把它放在 Derived 类中进行编译。我不想制作两个不同的测试代码

标签: c++ shadowing redefine inherited


【解决方案1】:

不要重新声明派生类的成员。 “受保护”一词确保了可见性。

如果您重新声明该成员,您将拥有一个新成员。这称为阴影。见,例如

【讨论】:

  • 我真的需要做阴影,因为这是我真正问题的一个例子。对于两个不同的类 Base,在 cvs 的两个不同分支中,我有相同的测试(派生一个主代码)。在一个 Base 类中,我有这个属性,而在另一个类 Base 中我没有这个属性,所以我必须把它放在 Derived 类中进行编译。我不想制作两个不同的测试代码
  • 在这种情况下,您也许应该重新提出您的问题。我不确定继承是否是实现该测试的最佳方式。建议:让测试类对该字段有一个吸气剂,并且您的测试代码只能使用吸气剂。然后,在吸气剂中你可以有 s.th.比如“如果 base class== XXX 那么 base.getA() ... else”。
【解决方案2】:

你可以这样做(但需要 C++11):

#include <type_traits>

// A way to check for 'attr' data member presence/absence using SFINAE
template<class T> constexpr auto missing_attr(T) -> decltype(T::attr, bool())
{
  return false;
}
constexpr bool missing_attr(...) { return true; }

struct Base { /* There might be (or not) a float data member 'attr' */ };

template<bool> struct Inject;
template<> struct Inject<true> { float attr = 0.0; };
template<> struct Inject<false> {};

struct Derived : public Base, protected Inject<missing_attr(Base())>
{
  void do_something_with_attr()
  {
    // Derived has only one 'float attr' (it can be from Base or from Inject).
    a *= a;
  }
};

还有其他方法可以检测数据成员是否存在,例如member detector idiom (C++03 兼容)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-11
    • 2011-03-11
    • 1970-01-01
    • 2010-10-20
    • 2011-04-21
    • 1970-01-01
    相关资源
    最近更新 更多