在c++ 11中可以在类之外执行继承吗?
Can I Perform inheritance outside of the class in C++11?
假设我想在类之外用不同的指针类型重载一个函数。我能在c++ 11中做到这一点吗?
struct Bird;
struct Bear;
struct Animal {
virtual Bird* AsBird() = 0;
virtual Bear* AsBear() = 0;
};
struct Bird : public Animal{
virtual Bird* AsBird(){ return this; }
virtual Bear* AsBear(){ return NULL; }
};
struct Bear : public Animal{
virtual Bird* AsBird(){ return NULL; }
virtual Bear* AsBear(){ return this; }
};
void Print(Animal* a){
cout << "I don't know what animal this is!" << endl;
}
void Print(Bear* b){
cout << "That's a bear!" << endl;
}
void Print(Bird* b){
cout << "That's a bird!" << endl;
}
int main(int argc, char* argv[]){
Animal* a = new Bear;
Bear* bear;
Bird* bird;
if (bear = a->AsBear()){
Print(bear);
} else if (bird = a->AsBird()){
Print(bird);
}
return 0;
}
这段代码可以工作,但它绝对是可怕的。我尝试过使用模板和auto,但是编译器不希望与我的邪恶实验有任何关系。有合法的方式来做这件事吗?
您所做的是通过改变参数的类型来重载 Print
free函数,没有涉及继承,这是完全合法的。
但是你不需要它(或任何dynamic_cast-like你所做的):你应该做的是在你的Animal
基类中添加一个virtual void Print() const = 0
,而不是在每个派生类中重写它。
例子:
struct Animal {
virtual void Print() const = 0;
};
struct Bird : public Animal{
void Print() const { cout << "That's a bird!n"; }
};
struct Bear : public Animal{
void Print() const { cout << "That's a bear!n"; }
};
int main(){
Animal* a = new Bear;
a->Print();
Animal* b = new Bird;
b->Print();
}
正如quantdev所指出的,传统的方法是在你的类层次结构中添加一个虚拟函数。
但是,如果您不想这样做,您可以使用dynamic_cast
,它是专门为这样的目的而发明的。
struct Animal {
virtual ~Animal() {} // base class must have a virtual method to use dynamic_cast
};
...
if (bear = dynamic_cast<Bear*>(a)){
Print(bear);
} else if (bird = dynamic_cast<Bird*>(a)){
Print(bird);
}
这比你现有的要好一点:如果你添加另一个继承类,你不必改变你的基类;你只需要改变你的main
函数并添加一个新的打印函数。
如果这仍然是"可怕的",也许你应该把Print
作为一个虚函数。
这看起来像是访问者模式的一个用例。
struct Bird;
struct Bear;
struct Visitor
{
virtual void Visit(Bird& x) = 0;
virtual void Visit(Bear& x) = 0;
};
struct PrintVisitor : Visitor
{
void Visit(Bird& x) override { cout << "That's a bird!" << endl; };
void Visit(Bear& x) override { cout << "That's a bear!" << endl; };
};
struct Animal
{
virtual void Accept(Visitor& v) = 0;
};
struct Bird : public Animal
{
void Accept(Visitor& v) override { v.Visit(*this); }
};
struct Bear : public Animal
{
void Accept(Visitor& v) override { v.Visit(*this); }
};
int main(int argc, char* argv[])
{
Bear bear;
Bird bird;
PrintVisitor visitor;
Animal* a = &bear;
a->Accept(visitor);
a = &bird;
a->Accept(visitor);
}
当然,使Print
成为一个虚成员函数可能更容易。
AsBear
, AsBird
函数,您只是重新实现了dynamic_cast
。
对于Print
的过载,这里最简单的解决方案是使Print
成为Animal
层次结构中的virtual
函数。
我推荐的解决方案是使用访问者模式。因为这似乎是你试图通过解耦Print
函数和类层次结构来做的。
#include <iostream>
struct Bird;
struct Bear;
struct Animal {
struct Visitor {
virtual void operator()(const Bird *) const = 0;
virtual void operator()(const Bear *) const = 0;
};
virtual void Accept(const Visitor &visitor) const = 0;
};
struct Bird : public Animal {
virtual void Accept(const Visitor &visitor) const override {
visitor(this);
}
};
struct Bear : public Animal {
virtual void Accept(const Visitor &visitor) const override {
visitor(this);
}
};
struct Print : public Animal::Visitor {
virtual void operator()(const Bird *) const override {
std::cout << "Bird" << std::endl;
}
virtual void operator()(const Bear *) const override {
std::cout << "Bear" << std::endl;
}
};
int main() {
Bird bird;
Animal *animal = &bird;
animal->Accept(Print());
}
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 继承函数的重载解析
- C++,系统无法执行指定的程序
- 使用C++中的模板和运算符重载执行矩阵运算
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 继承期间显示未知行为的子类
- 执行函数时导致崩溃的变量
- 当中间类跳过实现时,在继承层次结构中执行哪种虚拟方法
- 继承类上的运算符new和delete.操作员删除未执行
- 执行覆盖的继承函数
- 如何对继承构造函数执行正确的SFINAE
- 继承类的对象的析构函数执行
- 在c++ 11中可以在类之外执行继承吗?
- 如何对多态继承层次结构执行灵活的序列化
- 多重继承时的执行顺序
- 多级继承构造函数的执行
- 多站点执行:摆脱带有继承的虚拟表(遗留代码)
- 继承层次结构:构造函数和析构函数执行顺序
- 继承,选择性方法执行
- 如何使用多重继承执行强制转换