C ++中的多重定义错误,使用头文件

时间:2014-05-25 20:23:09

标签: c++ linker-errors undefined-reference

我刚接触C ++编程,但有一些Java经验。我创建了一个非常基本的类Dog.cpp及其头文件Dog.hpp。 Netbeans不会构建项目,给我一个错误,说明构造函数和getAge函数的多个定义。就我而言,我已经在头文件中声明了构造函数和函数,并在类文件中定义它们。我哪里出错?

提前致谢!

Dog.hpp:

#include <iostream>
using namespace std;
class Dog 
{
public:
    Dog(int someAge);           // Constructor
    ~Dog();                     // Destructor
    int getAge() const;         // function prototype
private:
    int itsAge;                 // age variable

};

Dog.cpp:

#include "Dog.hpp"
using namespace std;


Dog::Dog(int anAge) 
{
    cout << "Dog created \n";
}

int Dog::getAge() const
{
    return itsAge;
}

** main.cpp

#include <iostream>
#include "Dog.cpp"

int main() 
{
    Dog aDog(5);
    cout << aDog.getAge();
    return 0;
}

Netbeans输出:

"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory `/home/david/NetBeansProjects/C++/SAMS - Hour 10'
"/usr/bin/make"  -f nbproject/Makefile-Debug.mk dist/Debug/GNU-Linux-x86/sams_-_hour_10
make[2]: Entering directory `/home/david/NetBeansProjects/C++/SAMS - Hour 10'
mkdir -p build/Debug/GNU-Linux-x86
rm -f build/Debug/GNU-Linux-x86/main.o.d
g++    -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.cpp
mkdir -p build/Debug/GNU-Linux-x86
rm -f build/Debug/GNU-Linux-x86/Dog.o.d
g++    -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/Dog.o.d -o build/Debug/GNU-Linux-x86/Dog.o Dog.cpp
mkdir -p dist/Debug/GNU-Linux-x86
g++     -o dist/Debug/GNU-Linux-x86/sams_-_hour_10 build/Debug/GNU-Linux-x86/main.o build/Debug/GNU-Linux-x86/Dog.o  
build/Debug/GNU-Linux-x86/Dog.o: In function `Dog::Dog(int)':
/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:12: multiple definition of `Dog::Dog(int)'
build/Debug/GNU-Linux-x86/main.o:/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:12: first defined here
build/Debug/GNU-Linux-x86/Dog.o: In function `Dog::Dog(int)':
/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:12: multiple definition of `Dog::Dog(int)'
build/Debug/GNU-Linux-x86/main.o:/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:12: first defined here
build/Debug/GNU-Linux-x86/Dog.o: In function `Dog::getAge() const':
/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:18: multiple definition of `Dog::getAge() const'
build/Debug/GNU-Linux-x86/main.o:/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:18: first defined here
build/Debug/GNU-Linux-x86/main.o: In function `main':
main.cpp:(.text+0x6d): undefined reference to `Dog::~Dog()'
main.cpp:(.text+0x7f): undefined reference to `Dog::~Dog()'
collect2: error: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-Linux-x86/sams_-_hour_10] Error 1
make[2]: Leaving directory `/home/david/NetBeansProjects/C++/SAMS - Hour 10'
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory `/home/david/NetBeansProjects/C++/SAMS - Hour 10'
make: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 931ms)

2 个答案:

答案 0 :(得分:5)

似乎您在带有函数main的模块中包含了带有成员函数定义的cpp模块(Dog.cpp)。您应该只包含标题。

按以下方式更改Main.cpp

#include <iostream>
#include "Dog.hpp"

int main() 
{
    Dog aDog(5);
    cout << aDog.getAge();
    return 0;
}

考虑到您忘记在construtor中设置数据成员itsAge。它应该看起来像

Dog::Dog(int anAge) : itsAge( anAge )  
{
    cout << "Dog created \n";
}

你也忘了定义析构函数。

您可以在类定义中编写例如以下方式

class Dog 
{
public:
    Dog(int someAge);           // Constructor
    ~Dog() = default;           // Destructor
    int getAge() const;         // function prototype
private:
    int itsAge;                 // age variable

};

只要编译器支持此说明符。

答案 1 :(得分:1)

尝试在“Dog.hpp”中执行此操作:

#ifndef HEADER_GUARD  // Top of file
#define HEADER_GUARD

/* Code in your class here. */

#endif  // End of file

或者在文件顶部:

#pragma once

前一代码块将告诉预处理器只在代码中包含代码,只要未定义头保护定义(例如“FILENAME_HPP”)。如果条件通过则立即定义,因此代码只应加载一次。

后一个块也可以在大多数编译器上运行 - 并且可能更有效 - 包括g ++和Visual C ++。它告诉编译器只处理一次文件。

此外,您似乎缺少类的析构函数的定义。

另一个编辑:还有一件事,#include .cpp文件的编程习惯非常糟糕。始终#include与其关联的标头文件。