C++ 构造函数和g+的问题+;编制配方

C++ 构造函数和g+的问题+;编制配方,c++,class,inheritance,compiler-errors,g++,C++,Class,Inheritance,Compiler Errors,G++,我正在使用应用于C++11的函数创建一个cpp程序。尽管代码看起来正确且没有语法错误,但我在编译时收到了以下消息: /tmp/cce9dpew.o: In function `Object::Object()': classes.cpp:(.text+0xd): undefined reference to `vtable for Object' /tmp/cce9dpew.o: In function `Object::~Object()': classes.cpp:(.text+0x45):

我正在使用应用于C++11的函数创建一个cpp程序。尽管代码看起来正确且没有语法错误,但我在编译时收到了以下消息:

/tmp/cce9dpew.o: In function `Object::Object()':
classes.cpp:(.text+0xd): undefined reference to `vtable for Object'
/tmp/cce9dpew.o: In function `Object::~Object()':
classes.cpp:(.text+0x45): undefined reference to `vtable for Object'
/tmp/cce9dpew.o:(.rodata._ZTI6String[_ZTI6String]+0x10): undefined reference to `typeinfo for Object'
collect2: error: ld returned 1 exit status
我必须在这里补充一点,如果我把所有这些.cpp和.h文件放在一个文件中,它会运行Aok打印构造函数和析构函数。 有人能帮忙吗?代码如下。 编译我用来同时运行它们的配方:g++-std=c++0x classes.h classes.cpp mainiz.cpp

h类:

#ifndef CLASSES_H
#define CLASSES_H

#include <iostream>
#include <cstring>
using namespace std;

class Object
{
    private:
        int id;
    public:
        Object();
        ~Object();
        void set_id(int ids);
        int get_id();
        void Equal(Object* bj) const;
        void Identical(Object* bj) const;
        virtual Object* clone();
        virtual void toString();        
};


class String:public Object
{
        string characters;
    public:
        String();
        ~String();
        void set_char(string a);
        string get_char();
        String* clone();
        void toString();    
        int Length();
        void Clear(string a);
        string& Concat(string &a);
        char At(char b);
        string& UpdateAt(string a,string charact);
        void Print(const string a) const;   
};

#endif //CLASSES_H
\ifndef类
#定义类
#包括
#包括
使用名称空间std;
类对象
{
私人:
int-id;
公众:
对象();
~Object();
无效集合id(内部id);
int get_id();
无效相等(对象*bj)常量;
无效相同(对象*bj)常量;
虚拟对象*克隆();
虚拟void toString();
};
类字符串:公共对象
{
字符串;
公众:
字符串();
~String();
void set_char(字符串a);
字符串get_char();
字符串*clone();
void toString();
int Length();
空白清除(字符串a);
字符串和Concat(字符串和a);
char At(char b);
string&UpdateAt(字符串a,字符串字符);
无效打印(常量字符串a)常量;
};
#endif//CLASSES\u H
classes.cpp:

#include <iostream>
#include <cstring>

#include "classes.h"

using namespace std;

//FOR OBJECT CLASS
Object::Object(){ cout << "An object just got created." << endl;}

Object::~Object(){ cout << "An object just got destroyed." << endl; }

void Object::set_id(int ids) { this->id = ids; }
int Object::get_id() { return this->id;}

void Object::Equal(Object* bj) const
{
    if((this->id == bj->id))
    {
        cout << "The objects are equal." << endl;
    }
    else
    {
        cout << "The objects are not equal." <<endl;
    }
}

void Object::Identical(Object* bj) const
{
    if(this==bj)
    {
        cout << "The objects are identical." <<endl;
    }
    else
    {
        cout << "The objects are not identical." <<endl;
    }
}

//FOR STRING CLASS
String::String(){ cout << "String just created" << endl;}

String::~String(){ cout << "String to be destroyed" << endl;}

void String::set_char(string a) { this->characters = a;}
string String::get_char() { return this->characters;}

String* String::clone() { return this;}
void String::toString() {cout << "characters" << endl;}

int String::Length()
{ 
    string a = this->characters;
    return a.length();  
}

void String::Clear(string a)
{
    this->characters.clear();
}

string& String::Concat(string &a){  return (this->characters.append(a));}

char String::At(char b) { return (this->characters.find(b)); }

string& String::UpdateAt(string a,string charact)
{
    int position=this->characters.find(charact);
    return this->characters.replace(position,1,a);  
}

void String::Print(const string a) const { cout << "print of string:" << a << endl; }
#包括
#包括
#包括“classes.h”
使用名称空间std;
//对于对象类
对象::对象()
{

cout
Object::clone
Object::toString
已声明但从未实现

如果您想让它们保持未实现状态,请将它们设置为纯虚拟的,如中所示

class Object {
  virtual Object* clone() = 0;
};

Object::clone
Object::toString
已声明但从未实现

如果您想让它们保持未实现状态,请将它们设置为纯虚拟的,如中所示

class Object {
  virtual Object* clone() = 0;
};

将对象类的析构函数设置为“virtual”,则会因对Object::clone和Object::toString的未定义引用而出现另一个错误

你可以试试Igor建议的,但是你当前的主流.CPP代码不能工作,因为C++不允许一个纯虚拟方法的类的实例。 您可以尝试以下代码:

class Object {
  virtual ~Object();

  virtual Object* clone();
  virtual void toString();
};

Object* Object::clone() {
  // Make your implementation here
  return nullptr;
}

void Object::toString() {
  // Make your implementation here
}

将对象类的析构函数设置为“virtual”,则会因对Object::clone和Object::toString的未定义引用而出现另一个错误

你可以试试Igor建议的,但是你当前的主流.CPP代码不能工作,因为C++不允许一个纯虚拟方法的类的实例。 您可以尝试以下代码:

class Object {
  virtual ~Object();

  virtual Object* clone();
  virtual void toString();
};

Object* Object::clone() {
  // Make your implementation here
  return nullptr;
}

void Object::toString() {
  // Make your implementation here
}

上面给出的任何解决方案都不正确。问题出在我的编译配方中。这些函数是在C++11之后开始存在的,因此,如果您使用类似的方法,您的编译配方应该是:

g++-g-std=c++11-o可执行文件.cpp main.cpp


上面给出的任何解决方案都不正确。问题出在我的编译配方中。这些函数是在C++11之后开始存在的,因此,如果您使用类似的方法,您的编译配方应该是:

g++-g-std=c++11-o可执行文件.cpp main.cpp


这回答了你的问题吗?在一两个旁注上,和
Print()
不应该使用
std::string
参数。@ThomasSablik感谢您共享此链接!我阅读了它,从我的理解来看,我必须用我的虚拟对象更改某些内容或使我的构造函数虚拟化?@KenY-N为什么我不应该使用它?我必须在函数中的所有内容前面编写std::为什么不呢建议?@ScatterBrainer Igor Tandetnik为您的问题提供了解决方案。这是否回答了您的问题?在一两个旁注上,以及
Print()
不应该使用
std::string
参数。@ThomasSablik感谢您共享此链接!我阅读了它,从我的理解来看,我必须用我的虚拟对象更改某些内容或使我的构造函数虚拟化?@KenY-N为什么我不应该使用它?我必须在函数中的所有内容前面编写std::为什么不呢ScatterBrainer Igor Tandetnik建议了解决问题的方法。谢谢你的回答!“因为C++不允许一个纯虚拟方法的类的实例。”我很难理解这一点……你能解释一下吗?当然,一个虚拟表存储虚拟方法稍后会对每个实例使用。一个虚拟表允许C++类继承,正如你可能已经知道的,一个子只允许重写父的虚拟方法,我理解它是取代父的ME。方法与vtable中的子方法一起使用。纯虚拟方法声明为:“virtual void MyMethod()=0,这意味着MyMethod没有主体,并且vtable中的字段为空,因此当链接器搜索该方法的定义时,它会遇到问题,因为它不知道要使用哪个定义。该实例不完整,因为它声明了没有实际代码的方法。希望我解决了您的疑问。感谢您的回答!“因为C++不允许使用纯虚方法来实现类的实例。"我很难理解这一点……你能解释一下吗?当然,一个虚拟表存储虚拟方法稍后会对每个实例使用。一个虚拟表允许C++类继承,正如你可能已经知道的,一个子只允许重写父的虚拟方法,我理解它是取代父的ME。方法与vtable中的子方法一起使用。纯虚拟方法声明为:“virtual void MyMethod()=0,这意味着MyMethod没有主体,并且vtable中的字段为空,因此当链接器搜索该方法的定义时,它会遇到问题,因为它不知道要使用哪个定义。实例不完整,因为它声明了没有实际代码的方法。希望我解决了您的疑问。问题是我不知道不希望允许用户克隆对象或