проблема с конструкторами и рецептом компиляции g ++ - PullRequest
1 голос
/ 17 января 2020

Я создаю программу cpp с использованием функций, которые применяются к C ++ 11. Несмотря на то, что код кажется правильным и не имеет синтаксических ошибок, я получаю это сообщение при компиляции:

/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 печать конструктор и деструктор Cout просто отлично. Может кто-нибудь помочь? Код ниже. рецепт компиляции, который я использовал для запуска их всех вместе: g ++ -std = c ++ 0x classes.h классы. 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

классы. 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; }

mainiz. cpp:

#include <iostream>
#include <cstring>

#include "classes.h"

using namespace std;

int main()
{
    Object k;
    Object *st = new String;
    String d;
}

Ответы [ 3 ]

2 голосов
/ 17 января 2020

Делая деструктор для класса Object «виртуальным», вы получите еще одну ошибку для неопределенной ссылки на Object :: clone и Object :: toString.

Вы можете попробовать то, что предложил @Igor, но ваш текущий mainiz. 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
}
1 голос
/ 17 января 2020

Object::clone и Object::toString объявлены, но никогда не реализованы.

Если вы хотите оставить их нереализованными, сделайте их чисто виртуальными, как в

class Object {
  virtual Object* clone() = 0;
};
0 голосов
/ 20 января 2020

Ни одно из приведенных выше решений не было правильным. Проблема была в моем рецепте компиляции. Эти функции начали существовать после C ++ 11, поэтому, если вы используете что-то подобное, ваш рецепт компиляции должен быть:

g ++ -g -std = c ++ 11 -o исполняемый файл. cpp main. cpp

...