2

C++の再定義には疑問があります。Derived クラスでメモリを割り当てるので、このメモリは Base クラスで予約する必要があります。したがって、基本クラスの属性は派生クラスの属性と同じであると考える必要がありますが、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 の 2 つのブランチの、各ブランチに 1 つずつ、2 つの異なるクラス Base に対して、同じテスト (メイン コードの派生) があります。

このクラスBaseの1つにはこの属性があり、他のクラスBaseにはこの属性がないため、コンパイルのためにDerivedクラスに配置する必要があります。

2 つの異なるテスト コードを作成する必要がないため、属性をオーバーライドする必要があります。

4

2 に答える 2

3

次のようなことができます (ただし 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;
  }
};

データ メンバーが存在するかどうかを検出する方法は他にもあります。たとえば、メンバー検出イディオム(C++03 互換) があります。

于 2014-03-31T11:22:41.400 に答える
3

派生クラスのメンバーを再宣言しないでください。「保護された」という言葉は、可視性を保証します。

メンバーを再宣言すると、新しいメンバーが作成されます。これをシャドウイングと呼びます。たとえば、参照してください

于 2014-03-31T08:10:21.500 に答える