C++ 抽象类采用派生类参数
c++ abstract class takes derived class parameter
我想创建一个具有成员函数的类,该函数引用另一个类,其中两个类都派生自抽象类。我收到一个编译器错误,即类容器是抽象的,因为它没有实现 addElem()。
class Ielem
{
public:
virtual void action() = 0;
};
class Elem: public Ielem
{
public:
void action() {};
void extra() {};
};
class Icontainer
{
public:
virtual void addElem(Ielem &elem) = 0;
};
class Container: public Icontainer
{
public:
void addElem(Elem &elem) { elem.extra(); };
};
int main(int argc, char* argv[])
{
Elem e;
Container c;
c.addElem(e);
return 0;
}
这似乎应该有效,因为任何对 Elem 的引用也是对 Ielem 的引用。如果我使 Container::addElem 引用 Ielem,它就会编译。但是 Container::addElem() 不能调用 Elem::extra(),除非我使用 dynamic_cast,这在我正在使用的嵌入式编译器上不可用,或者常规强制转换,这不是类型安全的。
建议?
这是
错误的方式:基类Icontainer
指定addElem
可以将任何Ielem
对象作为参数,但在派生类中,您只接受Elem
。这是一个"更窄"的类型,因此违反了基类中指定的合约"我会接受你扔给我的任何Ielem
"。
我认为模板将是这里的解决方案。您甚至不再需要基类。像这样:
class Elem
{
public:
void action() {};
void extra() {};
};
template<typename ElemType>
class Container
{
public:
void addElem(ElemType &elem) { elem.extra(); };
};
int main(int argc, char* argv[])
{
Elem e;
Container<Elem> c;
c.addElem(e);
return 0;
}
作为奖励,您现在可以将Container
与具有extra()
功能的任何类型一起使用,并且它可以正常工作。
问题只是您的虚拟方法与旨在重载它的具体方法没有相同的签名; 因此编译器将其视为完全不同的函数并抱怨,因为您没有实现void addElem(Ielem &elem)
。 这是一个解决方案,你可能不想要——
class Icontainer
{
public:
virtual void addElem(Elem &elem) = 0; //Ielem -> Elem
};
这取决于你所有其他的约束,但我认为我会做的——似乎符合一般设计准则,例如 Sutter 和 Alexandreascu,是创建一个具有完整接口的中间抽象类——
class Melem: public Ielem
{
public:
// void action() {}; //Already have this form Ielem
void extra() = 0;
};
然后
class Icontainer
{
public:
virtual void addElem(Melem &elem) = 0;
};
class Container: public Icontainer
{
public:
void addElem(Melem &elem) { elem.extra(); };
//*Now* we're implementing Icontainer::addElem
};
相关文章:
- 在派生函数中指定void*参数
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- 使用 std::enable_if 限制派生类的模板参数时出现编译错误
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 创建派生自可变参数模板包的类型元组
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 派生类(构造函数具有参数)和基类(构造函数缺少参数)之间没有可行的转换
- C++派生类重载函数(带有 std::function 参数)不可见
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- 从模板参数派生的类
- C++ 如何使派生类自动获取基类参数
- C++ 将派生类的成员函数指针作为参数传递时选择了错误的模板专用化
- 如何在派生类中正确覆盖具有不同参数的函数?
- 根据参数创建派生类的新实例
- 具有派生参数的函数重写
- 将派生类作为参数传递给方法,该方法是具有智能指针的基类
- 将方法参数类型更改为子类中的派生类
- 派生类的模板参数推导
- 将派生类构造函数参数传递给受保护的成员
- 具有原始方法参数派生类的 C++ 重载方法参数