0

使用此代码:

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这样我就不必在每个类中创建这些getset功能,如 Carrot 或 Peas 等?

如果我这样做了:

inline virtual std::string getPlantName( return _plantName; );

那行得通吗?然后我会添加std::string _PlantName;class Plant然后当我从中创建时CarrotPlant我会得到所有相同的函数,并且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() { }
4

3 回答 3

0

您可以通过将方法添加到类声明来更正错误:

class Carrot : public Plant
{
public:
   Carrot();
   ~Carrot();

  virtual std::string getPlantName();

private:
  std::string _plantName;

}; 

或者,如果所有植物都有名称,您可以改为在 Plant 类中定义方法(可能在 plant.cpp 中)。事实上,你必须定义它,除非你声明它是纯虚拟的。

于 2013-05-28T22:56:25.787 回答
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的指针时将调用派生类的实现)。PlantCarrot

请注意,如果您想确保永远不会实例化一个Plant对象,您应该使任何非通用函数(如DoSomethingTypeSpecific()Carrot 或 Flower 不同的做法)成为纯虚拟函数,并创建一个抽象基类。然后所有基类都必须实现这些功能。

这里的内联并没有真正的区别,只是在头文件或单独的 .cpp 文件中定义函数。通常,将实现保存在单独的文件中是个好主意,但如果您愿意,可以轻松内联这些小的 setter 和 getter。

于 2013-05-28T22:56:50.390 回答
0

您需要声明该函数。

class Carrot : public Plant
{
public:
    Carrot();
    ~Carrot();

    std::string getPlantName(); //Add this

private:
    std::string _plantName;

};

几点注意事项:

  • Carrot::getPlantName尽管许多 C++ 开发人员认为它是一种很好的形式,但它并不是绝对必要的。我个人更喜欢只在抽象基类中使用 virtuals,而在具体类中使用 none
  • 您可能需要添加virtual ~Plant() {}Plant课程中。您几乎总是希望具有虚拟方法的类也具有虚拟析构函数。
于 2013-05-28T22:58:54.040 回答