使用此代码:
class Plant
{
public:
virtual std::string getPlantName();
virtual void setPlantName(std::string s);
virtual std::string getPlantType();
virtual void setPlantType(std::string s);
};
class Carrot : public Plant
{
public:
Carrot();
~Carrot();
private:
std::string _plantName;
};
然后:
#include "Carrot.hpp"
Carrot::Carrot()
{
}
Carrot::~Carrot() { }
std::string Carrot::getPlantName() { return _plantName; }
我收到链接错误:
Carrot.cpp:16:21: Out-of-line definition of 'getPlantName' does not match any declaration in 'Carrot'
所以这里的目标是创建一个Plant类,其他类扩展为class Carrot : public Plant
但是,我不确定的是inline
我可以Plant
中的功能,以便我不必在每个get
和set
中创建这些功能像胡萝卜或豌豆等课程?
如果我这样做了:
inline virtual std::string getPlantName( return _plantName; );
那会有用吗?然后我会将std::string _PlantName;
添加到class Plant
,然后当我从Carrot
创建Plant
时,我会获得所有相同的函数,而Carrot
会有_plantName
之类的变量等等,是吗?
所以这将是:
class Plant
{
public:
inline virtual std::string getPlantName( return _plantName; );
virtual void setPlantName(std::string s);
virtual std::string getPlantType();
virtual void setPlantType(std::string s);
private:
std::string _plantName;
};
class Carrot : public Plant
{
public:
Carrot();
~Carrot();
};
#include "Carrot.hpp"
Carrot::Carrot()
{
setPlantName(CARROT::plantName);
}
Carrot::~Carrot() { }
答案 0 :(得分:0)
您可以通过将方法添加到类声明中来纠正错误:
class Carrot : public Plant
{
public:
Carrot();
~Carrot();
virtual std::string getPlantName();
private:
std::string _plantName;
};
或者,如果所有植物都有名称,您可以在Plant类中定义方法(可能在plant.cpp中)。实际上,除非将其声明为纯虚拟,否则必须对其进行定义。
答案 1 :(得分:0)
如果Plant
类的所有对象都应该有std::string
个类型和名称,那么您可能需要基类中的那些公共成员:
// Plant.hpp
class Plant
{
public:
Plant();
virtual ~Plant(); // virtual destructor!
virtual std::string getPlantName();
virtual void setPlantName(std::string s);
virtual std::string getPlantType();
virtual void setPlantType(std::string s);
protected:
std::string _plantName;
std::string _plantType;
};
// Plant.cpp
#include <Plant.hpp>
std::string Plant::getPlantName() { return _plantName; }
void Plant::setPlantName(std::string s) { _plantName = s; }
... same for type
使用class Carrot : public Plant
创建派生类时,该类将具有相同的数据成员和相同的函数。如果需要,您还可以覆盖它们(感谢virtual
关键字,当使用Plant
对象的Carrot
指针时,将调用派生类的实现。
请注意,如果你想确保永远不会实现Plant
对象,你应该制作任何非常见的函数(比如Carrot或Flower会做的不同的DoSomethingTypeSpecific()
)纯虚拟,并通过创建抽象基类。然后,所有基类都将具有来实现这些功能。
这里的内联并没有真正的区别,只需要在头文件或单独的.cpp文件中定义函数。通常,将实现保存在单独的文件中是个好主意,但如果您愿意,可以很容易地将这些小的setter和getter内联。
答案 2 :(得分:0)
您需要声明该功能。
class Carrot : public Plant
{
public:
Carrot();
~Carrot();
std::string getPlantName(); //Add this
private:
std::string _plantName;
};
几点说明:
Carrot::getPlantName
并非绝对必须是虚拟的,尽管许多C ++开发人员认为它是好的形式。我个人更喜欢只在抽象基类中使用虚拟,而在具体类中使用none virtual ~Plant() {}
添加到Plant
课程。您几乎总是希望使用虚方法的类也具有虚拟析构函数。