C++中的继承
Inheritance in C++
这是我的问题:我在 .h 文件中定义了一个虚拟方法,我想在从基类继承的类中调用它。 遗憾的是,派生类中的方法没有被调用。有没有更好的方法来实现我正在尝试做的事情?
#ifndef ofxBASE_SND_OBJ
#define ofxBASE_SND_OBJ
#include "ofConstants.h"
class ofxBaseSndObj {
public:
virtual string getType(){}
string key;
};
#endif
这是我的嗡嗡声课
#ifndef OFXSO_BUZZ
#define OFXSO_BUZZ
#include "ofxBaseSndObj.h"
class ofxSOBuzz : public ofxBaseSndObj
{
public:
string getType();
};
#endif
ofxSOBuzz.cpp
string ofxSOBuzz::getType()
{
string s = string("ofxSOBuzz");
printf(" ********* returning string type %s", s.c_str()); // doesn't get called!
return s;
}
然后在另一堂课上,我试着这样称呼它:
string ofxSndObj::createFilter(ofxBaseSndObj obj)
{
string str = obj.getType();
if(str.compare("ofxSOBuzz") == 0)
{
printf(" all is well ");
}
}
在上面的方法中,我需要能够传入许多对象之一,这些对象都扩展了ofxBaseSndObj对象。任何建议或指示将不胜感激。谢谢!
更改此行:
string ofxSndObj::createFilter(ofxBaseSndObj obj)
自
string ofxSndObj::createFilter(ofxBaseSndObj& obj)
您正在做的是按值传递(传递副本)。
这意味着您正在将对象复制到函数中。因为函数不知道你实际传递的类型,所以它只传递函数声明中定义的类型,因此它会复制基类(这称为切片问题)。
解决方案是通过引用传递。
如果您不希望函数修改对象(也许这就是您按值传递的原因,因此它无法更改原始值),则传递 const 引用。
class ofxBaseSndObj
{
public:
virtual string getType() const;
// If the method does not change the object mark it const
string key;
};
string ofxSndObj::createFilter(ofxBaseSndObj const& obj)
{
// allowed to call this if getType() is a const
string str = obj.getType();
if(str.compare("ofxSOBuzz") == 0)
{
printf(" all is well ");
}
}
您需要将实例传递给 createFilter 作为指向对象的指针(或引用)。 您是按值传递的,这会导致编译器将用作参数的派生对象复制到基类的实例中。 当它这样做时,您将失去它最初是派生类型的事实。
正如所写的那样,您的代码实际上不应该编译,因为 ofxBaseSndObj::getType 的声明不会返回任何内容。 您的意思是将其作为抽象方法还是返回空字符串?
如果你把它做成一个抽象方法,那么编译器会抱怨试图在你的ofxSndObj::createFilter方法中实例化一个抽象类。
在C++中称为"切片"。
将复制构造函数和运算符=设为私有是防止此错误再次发生的有效方法。
例如:
class ofxBaseSndObj {
public:
virtual string getType(){}
string key;
private:
ofxBaseSndObj(const ofxBaseSndObj& rhs);
ofxBaseSndObj& operator=(const ofxBaseSndObj& rhs);
};
如果没有其他充分的理由,您应该使用RTTI内置的C++。然后可以使用类型标识运算符。如果默认情况下未打开此功能,请查看编译器文档以将其打开。
其他人已经解决了切片问题。 然后你问 好吧,让我说,我知道我需要做一些事情来确定基类型,但是还有什么比做枚举查找来确定继承对象的类型更优雅的吗?
查询和切换对象的类型是一个糟糕的设计,它错过了 OO 方法的重点。
而不是
string ofxSndObj::createFilter(ofxBaseSndObj& obj)
{
string str = obj.getType();
if(str.compare("ofxSOBuzz") == 0)
{
// do ofxSOBuzz - specific thing
}
else if(str.compare("some other derived class") == 0)
{
// do stuff for other derived classes
}
// etc...
}
使有趣的行为成为虚拟函数:
class ofxBaseSndObj {
public:
// get rid of getType()
virtual void HelpCreateFilter() = 0;
};
string ofxSndObj::createFilter(ofxBaseSndObj& obj)
{
// Let the derived class do it's own specialized work.
// This function doesn't need to know what it is.
obj.HelpCreateFilter();
// rest of filter creation
}
为什么这比原始版本更好? 因为如果将来将 ofxBaseSndObj 的派生类添加到系统中,则不需要修改ofxSndObj::createFilter
。 您的版本需要针对每个新的派生类进行扩展。 如果不清楚,请尝试发布更多代码 - 我无法从您的代码或类名中看出这些函数应该做什么。
dynamic_cast或type_id
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 公共与私人继承
- 如何创建从同一类继承的不同对象的向量
- 如何从另一个文件继承私有成员变量和公共函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 带有继承的C++工厂
- 我应该避免多重实现继承吗
- C++继承更改成员
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 关于C++中具有多重继承"this"指针的说明
- 尝试使用继承和模板实现CRTP.Visual Studio正在生成编译器错误
- 如何在QT Creator上将QWidget声明为继承类的对象