C++:对'CYourClass::Method()&#39的未定义引用;

2022-03-12 00:00:00 reference undefined g++ c++

我正在努力找出类继承中代码的问题。我找了很多地方,但似乎找不到正确的答案。在此之前,我在修复许多错误方面取得了一些进展,但还没有完全完成。

我遇到的主要问题是在我的文件中的许多实例中对方法或构造函数的未定义引用。我确信我可能只是在某个地方遗漏了一些非常简单的东西,但是作为C++的新手,我很难准确地指出问题所在。

下面是我的代码的文件:

dog.h

#ifndef DOG_H
#define DOG_H

#include <string>

using namespace std;

class Dog{
    public:
        Dog();
        ~Dog(){};
        string dogName = "";
        string Breed = "";
        int age = 0;
        int weight = 0;
        bool subjectToDiscount = false;
        int riskWeight = 0;
        float riskPremium = 0;
        float basePremium = 0;
        virtual float getPremium();
        virtual Dog getDog(char b);
    protected:
        virtual float getBasePremium();
    private:
};

#endif //DOG_H

dog.cpp

#include <iostream>
#include <string>

#include "dog.h"
#include "breeds.h"

using namespace std;

//---default constructor---//
Dog::Dog(){
};

//---methods---//
float Dog::getBasePremium(){
    float val = 0;
    //calculate base premium based on weight
    return val;
};

float Dog::getPremium(){
    float val = 0;
    //calculate actual premium for the dog in question
    if(this->riskWeight == 0){
        val = this->basePremium;
    }else if(this->weight > this-> riskWeight){
        val = this->riskPremium;
    }else val = this->basePremium;

    //add discount if applicable
    if(this->subjectToDiscount && this->age > 13) val *= 0.80;

    //add 25% if over 50kg
    if(this->weight > 50) val *= 1.25;

    return val;
};

Dog Dog::getDog(char b){
    bool recognized = false;
    Dog *pup; 

    while(!recognized){
        switch (b)
        {
        case 'p':
            pup = new Pitbull();
            recognized = true;
            break;
        case 'd':
            pup = new Doberman();
            recognized = true;
            break;
        case 'r':
            pup = new Rottweiler();
            recognized = true;
            break;
        default:
            cout << "Breed code not recognized, please try again...
";
            break;
        }
    }
    return *pup;
}

int main(){
    return 0;
}

breeds.h

#ifndef BREEDS_H
#define BREEDS_H

#include "dog.h"
#include <string>

using namespace std;

class Pitbull : public Dog{
    public:
        Pitbull();
        ~Pitbull(){};
    protected:
    private:
};

class Doberman : public Dog{
    public:
        Doberman();
        ~Doberman(){};
    protected:
    private:
};

class Rottweiler : public Dog{
    public:
        Rottweiler();
        ~Rottweiler(){};
    protected:
    private:
};

#endif //BREEDS_H

breeds.cpp

#include <iostream>
#include <string>

#include "dog.h"
#include "breeds.h"

using namespace std;

//---constructors---//
Pitbull::Pitbull(){
    this->Breed = "a Pitbull";
    this->basePremium = 30.20f;
    this->riskPremium = 35.15f;
    this->riskWeight = 20;
    this->subjectToDiscount = false;
}

Doberman::Doberman(){
    this->Breed = "a Doberman";
    this->basePremium = 28.16f;
    this->riskPremium = 30.00f;
    this->riskWeight = 35;
    this->subjectToDiscount = true;
}

Rottweiler::Rottweiler(){
    this->Breed = "a Rottweiler";
    this->basePremium = 28.00f;
    this->riskPremium = 29.75f;
    this->riskWeight = 45;
    this->subjectToDiscount = false;
}

int main(){
    return 0;
}

main.cpp

#include <iostream>
#include <iomanip>
#include <string>

#include "dog.h"
#include "breeds.h"

using namespace std;

int getDogCount(){
    int retVal = 0;
    cout << "Please enter the number of dogs in your household: ";
    cin >> retVal;
    return retVal;
}

void run(){
    cout << setiosflags(ios::fixed);
    cout << setprecision(2);

    int dogCount = 0;
    float totalPremium = 0;

    dogCount = getDogCount();

    for(int i = 1; i <= dogCount; i++){
        float premium = 0;
        char breedCode = '.';
        string dogName = "";
        Dog pup;

        cout << "Enter the name of dog #" << i << ": ";
        cin.ignore();
        getline(cin, dogName);

        cout << "Enter the breed code for " << dogName << ": ";
        cin >> breedCode;
        cin.ignore();

        pup = pup.getDog(breedCode);
        pup.dogName = dogName;

        cout << "Enter the current age for " << dogName << ": ";
        cin >> pup.age;
        cin.ignore();

        cout << "Enter the current weight for " << dogName << ": ";
        cin >> pup.weight;

        premium = pup.getPremium();

        cout << "
";
    }
}

int main(){
    run();

    return 0;
}

以下是我在尝试编译3个.cpp文件后收到的错误:

dog.cpp

C:UserswhitlAppDataLocalTempccFdz6zr.o: In function `Dog::getDog(char)':
C:SandboxC++BeginningWooffurs/dog.cpp:46: undefined reference to `Pitbull::Pitbull()'
C:SandboxC++BeginningWooffurs/dog.cpp:50: undefined reference to `Doberman::Doberman()'
C:SandboxC++BeginningWooffurs/dog.cpp:54: undefined reference to `Rottweiler::Rottweiler()'
collect2.exe: error: ld returned 1 exit status

breeds.cpp

C:UserswhitlAppDataLocalTempccbAKpbb.o: In function `Pitbull::Pitbull()':
C:SandboxC++BeginningWooffurs/breeds.cpp:10: undefined reference to `Dog::Dog()'
C:UserswhitlAppDataLocalTempccbAKpbb.o: In function `Doberman::Doberman()':
C:SandboxC++BeginningWooffurs/breeds.cpp:18: undefined reference to `Dog::Dog()'
C:UserswhitlAppDataLocalTempccbAKpbb.o: In function `Rottweiler::Rottweiler()':
C:SandboxC++BeginningWooffurs/breeds.cpp:26: undefined reference to `Dog::Dog()'
C:UserswhitlAppDataLocalTempccbAKpbb.o:breeds.cpp:(.rdata$_ZTV10Rottweiler[_ZTV10Rottweiler]+0x10): undefined reference to `Dog::getPremium()'
C:UserswhitlAppDataLocalTempccbAKpbb.o:breeds.cpp:(.rdata$_ZTV10Rottweiler[_ZTV10Rottweiler]+0x18): undefined reference to `Dog::getDog(char)'
C:UserswhitlAppDataLocalTempccbAKpbb.o:breeds.cpp:(.rdata$_ZTV10Rottweiler[_ZTV10Rottweiler]+0x20): undefined reference to `Dog::getBasePremium()'
C:UserswhitlAppDataLocalTempccbAKpbb.o:breeds.cpp:(.rdata$_ZTV8Doberman[_ZTV8Doberman]+0x10): undefined reference to `Dog::getPremium()'
C:UserswhitlAppDataLocalTempccbAKpbb.o:breeds.cpp:(.rdata$_ZTV8Doberman[_ZTV8Doberman]+0x18): undefined reference to `Dog::getDog(char)'
C:UserswhitlAppDataLocalTempccbAKpbb.o:breeds.cpp:(.rdata$_ZTV8Doberman[_ZTV8Doberman]+0x20): undefined reference to `Dog::getBasePremium()'
C:UserswhitlAppDataLocalTempccbAKpbb.o:breeds.cpp:(.rdata$_ZTV7Pitbull[_ZTV7Pitbull]+0x10): undefined reference to `Dog::getPremium()'
C:UserswhitlAppDataLocalTempccbAKpbb.o:breeds.cpp:(.rdata$_ZTV7Pitbull[_ZTV7Pitbull]+0x18): undefined reference to `Dog::getDog(char)'
C:UserswhitlAppDataLocalTempccbAKpbb.o:breeds.cpp:(.rdata$_ZTV7Pitbull[_ZTV7Pitbull]+0x20): undefined reference to `Dog::getBasePremium()'
C:UserswhitlAppDataLocalTempccbAKpbb.o:breeds.cpp:(.rdata$.refptr._ZTV3Dog[.refptr._ZTV3Dog]+0x0): undefined reference to `vtable for Dog'
collect2.exe: error: ld returned 1 exit status

main.cpp

C:UserswhitlAppDataLocalTempccgKyBTC.o: In function `run()':
C:SandboxC++BeginningWooffurs/main.cpp:30: undefined reference to `Dog::Dog()'
C:SandboxC++BeginningWooffurs/main.cpp:40: undefined reference to `Dog::getDog(char)'
C:SandboxC++BeginningWooffurs/main.cpp:50: undefined reference to `Dog::getPremium()'
C:UserswhitlAppDataLocalTempccgKyBTC.o:main.cpp:(.rdata$.refptr._ZTV3Dog[.refptr._ZTV3Dog]+0x0): undefined reference to `vtable for Dog'
collect2.exe: error: ld returned 1 exit status

感谢任何帮助我的人,我真的很感激。也请在我的代码上给我任何指点,以及如何更好地提出关于堆栈溢出的问题。


解决方案

看起来您正在执行如下操作:

g++ dog.cpp -o dog

如果没有-c标志(仅用于编译,不链接),编译器将尝试从该文件生成可执行文件。

一般来说,您需要执行以下操作之一:

  1. 单独编译每个CPP文件,然后在末尾链接
# compilation
g++ -c dog.cpp -o dog.o
g++ -c breeds.cpp -o breeds.o
g++ -c main.cpp -o main.o

# now link the 3 object files into the exe
g++ -o myApp main.o dog.o breeds.o
  1. 一次性编译
g++ -o myApp main.cpp dog.cpp breeds.cpp
  1. 使用Makefile
all : myApp

# dog.o depends on dog.cpp & breeds.h. When those change, run line below
dog.o: dog.cpp breeds.h
     gcc -c -o dog.o dog.cpp

breeds.o: breeds.cpp dog.h
     gcc -c -o breeds.o breeds.cpp

main.o: main.cpp breeds.h dog.h
     gcc -c -o main.o dog.cpp

# final app depends on the object files, when they change, recompile.
myApp: main.o dog.o breeds.o
     gcc -o myApp main.o dog.o breeds.o

clean:
    rm -f *.o 
  1. 使用某个IDE为您管理此功能(或使用类似cmake的工具)

相关文章