【发布时间】:2012-10-23 13:18:14
【问题描述】:
我有以下几点:
class Base
{
protected:
std::string _name;
public:
virtual ~Base(){}
const std::string &name;
Base()
: _name ("(no name)")
, name(_name)
{}
};
template <typename T>
class BaseH : public Base
{
public:
virtual ~BaseH() {}
BaseH() : Base() {}
T& operator~(){ ; return static_cast<T&>(*this);}
};
class One : public BaseH<One>
{
public:
One() : BaseH<One>() { _name = "One"; }
};
class Two
: public One
, public BaseH<Two>
{
public:
Two() : BaseH<Two>() { _name = "Two"; }
};
int main(int argc, char *argv[])
{
std::cout << Two().name << std::endl;
return 0;
}
我想从One 和BaseH<Two> 派生Two,因为Two 是One 的特化,而BaseH 中的operator~ 必须始终返回类型为调用它的对象。
编译错误明显是:
In constructor ‘Two::Two()’:
error: reference to ‘_name’ is ambiguous
error: candidates are: std::string Base::_name
error: std::string Base::_name
In function ‘int main(int, char**)’:
error: request for member ‘name’ is ambiguous
error: candidates are: const string& Base::name
error: const string& Base::name
在通过构造函数委托设置const 引用时,如何使One 和Two 中的_name 和name 都可访问?最干净的方法是什么?
【问题讨论】:
-
我怀疑这是否真的是CRTP。或者至少通过
virtual函数,你没有利用它。 -
@iammilind:不确定你的意思,但就其价值而言,这当然是“真实”代码的一小部分摘录
-
CRTP 通常在您想消除由于
virtual函数引起的开销时很有用(请参阅 wiki 链接)。在代码示例中,它没有利用它。您发布的可能是另一种形式的 CRTP。 -
@iammilind:您对如何完成上述操作有什么建议吗?
-
从您的代码中,我认为在任何类中都不需要
virtual析构函数,因为您使用的是 CRTP。如果您使用new T/delete pT将内存分配给BaseH<T>*,那么可能需要进行一些调整。但这必须详细讨论,值得另一个问题。您还可以提及您的设计目标,例如您想要实现的目标。
标签: c++ oop design-patterns inheritance crtp