0

我有这门课

struct B {
   B( int x=0 ) { }
   virtual void something() {
          std::cout << "B()";
   }
};

struct A { 
     B b;
     int a;
     A( int a, int b_ ) : a(a), b(b_) {a}
};

我已经实现了另一个 C 类

 struct C : public B {
   C( int x ) : B(b) { }
   virtual void something() {
          std::cout << "C()";
   }
}; 

让 A 使用 C 而不是 B 的最佳方法是什么?

我已经试过了:

struct A { 
         B  & b;
         int a;
         A( int a, B &b_ ) : a(a), b(b_) {a}
    };

但后来我必须使用std::map<int, A> which 给出编译错误:

'A::A' : no appropriate default constructor available.

所以我这样做了:

struct A { 
             B  & b;
             int a;
             A( int a=0, B &b_=B() ) : a(a), b(b_) {a}
        };

在我的主要

std::map<int,A> mmap;
for( int i=0;i<5;++i ) {
   auto & b = C();
   mmap.insert( std::make_pair(i,A(i,b) ) ) ;
}

但是一旦auto & b超出范围,这些 C 在 mmap 的 A 中的对象就会变成 B。

它不工作。如何解决?

4

1 回答 1

1

在 A 构造函数中,您尝试将 B 的临时实例分配给 B 的引用,这是非法的。

您要做的是通过指向此类的指针来更改此引用:

#include <iostream>
#include <memory>
#include <map>

using namespace std;

struct B {

   B( int x=0 ) { }
   virtual void something()
   {
        std::cout << "B()";
   }
};

struct A { 
        shared_ptr<B> b;
        int a;
        A( int a = 0, shared_ptr<B> b = shared_ptr<B>(new B()) ) : a(a), b(b) {}
};

struct C : public B {
    C( int x ) { }
    virtual void something()
    {
        std::cout << "C()";
    }
}; 

int main()
{
    shared_ptr<B> b = shared_ptr<B>( new C(0));
    // Polymorphic test
    b->something();

    A a (0, b);
    // map test
    map<int, A> my_map;
    my_map[0] = a;

    return 0;
};

如果您不能使用 C++11,只需通过裸指针更改智能指针并照常正确处理动态内存。甚至更好:使用 Chris 提到的 Boost 库。

于 2013-07-26T08:40:50.147 回答