我有文件::
//ClassA.h
#ifndef ClassA_H
#define ClassA_H
#pragma once
class ClassA
{
public:
void func1(){
}
ClassA(void) {
}
~ClassA (void) {
}
};
#endif
//ClassA1.h
#include "ClassA.h"
class ClassA1 {
ClassA<2> b;
};
//ClassA1.cpp
#include "ClassA1.h"
//main_file.cpp
#include "ClassA1.h"
#include "iostream"
int main (int argc , char** argv) {
std::cout<<"in main"<<std::endl;
}
所以这个编译得很好......一旦我在Class.h中的类外部定义类ClassA的函数,我就会在构建期间遇到以下错误
1> LINK : c:\users\adudeja\documents\visual studio 2010\Projects\Test\Debug\Test.exe not found or not built by the last incremental link; performing full link
1>ClassA1.obj : error LNK2005: "public: void __thiscall ClassA::func1(void)" (?func1@ClassA@@QAEXXZ) already defined in main_file.obj
1>ClassA1.obj : error LNK2005: "public: __thiscall ClassA::ClassA(void)" (??0ClassA@@QAE@XZ) already defined in main_file.obj
1>ClassA1.obj : error LNK2005: "public: __thiscall ClassA::~ClassA(void)" (??1ClassA@@QAE@XZ) already defined in main_file.obj
1>c:\users\adudeja\documents\visual studio 2010\Projects\Test\Debug\Test.exe : fatal error LNK1169: one or more multiply defined symbols found
那么在类和类内部定义函数之间有什么区别。
以下是非工作代码......
#ifndef ClassA_H
#define ClassA_H
#pragma once
class ClassA
{
public:
void func1();
ClassA(void);
~ClassA(void);
};
void ClassA::func1(){
}
ClassA::ClassA(void) {
}
ClassA::~ClassA (void) {
}
#endif
答案 0 :(得分:2)
那么在类和类内部定义函数之间有什么区别。
当你在类体中定义它时,它是隐式的inline
,并且可以在多个文件中定义内联函数。
非内联函数必须只定义一次。
因此,要么将非内联定义放入单个.cpp
文件中,而不是放在多个文件包含的标头中,要么使用inline
关键字进行定义。
答案 1 :(得分:0)
好的,让我们看看......
在您的示例中,没有在类声明之外定义函数。
ClassA1.cpp和main_file.cpp&#34;参见&#34; ClassA的定义。由于在内部定义的所有函数都被认为是inline
,即链接器根本不会将其视为单独的函数,并且没有什么可抱怨的。
但如果你把例如在课堂声明之外的func1()
(但仍在ClassA中),它不再被视为inline
,它是一个独立的功能。但是因为它仍然可以被两个编译单元看到,所以它可以在两个翻译单元中编译。
因此,当您尝试将两个目标文件链接在一起时,您有两个func1()
实例,并且链接器会抱怨。
解决方案是 :
使用模板会稍微限制您的选项,因为模板代码必须对其使用的每个翻译单元可见,即您不能在标题中声明它并在其他地方实现它,只留下选项1.上面。
后代码审核:
ClassA.hpp:
#ifndef ClassA_HPP
#define ClassA_HPP
class ClassA
{
public:
ClassA();
~ClassA();
void func1();
};
#endif
ClassA.cpp:
#include "ClassA.hpp"
void ClassA::func1()
{
// ...
}
ClassA::ClassA()
{
// ...
}
ClassA::~ClassA()
{
// ...
}
ClassA1.hpp:
#ifndef ClassA1_HPP
#define ClassA1_HPP
#include "ClassA.hpp"
// Your example still assumed that ClassA is a template,
// so I twisted that into an inheritance instead since
// ClassA isn't a template anymore, and if it *were* a
// template, it would change things significantly.
// Perhaps trying too much at once?
class ClassA1 : public ClassA
{
// ...
};
#endif
ClassA1.cpp:
#include "ClassA1.hpp"
// ...
main_file.cpp:
#include "ClassA1.hpp"
#include <iostream>
int main( int argc, char * argv[] )
{
std::cout << "in main" << std::endl;
return 0;
}