在c++中正确地扩展类
Properly extending a class in C++
代码:
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
,然后当我从Plant
创建Carrot
时,我得到所有相同的函数,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() { }
如果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
关键字,当使用指向Carrot
对象的Plant
指针时,派生类的实现将被调用)。
Plant
对象,你应该使任何非通用函数(如DoSomethingTypeSpecific()
,胡萝卜或花会做不同的事情)纯虚,并通过创建一个抽象基类。所有的基类都有来实现这些函数。这里的内联没有真正的区别,它只是在头文件或单独的.cpp文件中定义函数的问题。一般来说,将实现保存在一个单独的文件中是个好主意,但如果你愿意,这些小的setter和getter可以很容易地内联。
您可以通过在类声明中添加方法来纠正错误:
class Carrot : public Plant
{
public:
Carrot();
~Carrot();
virtual std::string getPlantName();
private:
std::string _plantName;
};
或者,如果所有植物都有名称,则可以在Plant类中定义方法(可能在in Plant .cpp中)。事实上,你必须定义它,除非你声明它是纯虚的。
你需要声明函数
class Carrot : public Plant
{
public:
Carrot();
~Carrot();
std::string getPlantName(); //Add this
private:
std::string _plantName;
};
注意事项:
- 您可能需要将
virtual ~Plant() {}
添加到Plant
类中。几乎总是希望带有虚方法的类也具有虚析构函数。
Carrot::getPlantName
不是必须是虚拟的,尽管许多c++开发人员认为这是一种很好的形式。我个人更喜欢只在抽象基类中使用虚拟,而在具体类中不使用虚拟相关文章:
- 如何正确地将分支添加到已存在的树中
- 如何正确地将带有指针的数组传递给函数
- 如何正确地推回然后遍历堆中对象的向量?
- 我是否不正确地集中了这些字符数组?
- 如何通过另一个对象中的命令正确地从一个对象返回数据
- 我怎样才能通过友谊正确地履行我的职能?
- C++:如何正确地将 deque::front() 返回的变量从函数中传递出去?
- 我应该如何正确地将packaged_task移动到 lambda?
- 如何正确地将SHA1CryptoServiceProvider转换为c ++?
- 如何正确地对 constexpr 函数进行单元测试
- 我的动态链接队列在同一输出流中调用时不正确地输出三个返回函数
- 如何正确地将boost::asio::buffers_iterator转换为InputIterator
- 如何正确地检查变量char中包含的字母
- 当试图交换可变模板类时,如何正确地重载operator=
- 如何正确地将 boost::optional<std::chrono::d uration> 作为函数参数?
- 如何在C++中正确地将我的语言字符输出到HTML文件中
- 如果我的类正确地管理了一个资源,那么拥有智能的poointer有什么意义
- 如何正确地编写这些条件,以便它们在控制台中工作
- 正确地编写一个类,并将pthread与vlc库和c++一起使用
- 在c++中正确地扩展类