酱坛子

专注C++技术 在这里写下自己的学习心得 感悟 和大家讨论 共同进步(欢迎批评!!!)

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  66 Posts :: 16 Stories :: 236 Comments :: 0 Trackbacks

公告

王一伟 湖南商学院毕业 电子信息工程专业

常用链接

留言簿(19)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 385366
  • 排名 - 64

最新随笔

最新评论

阅读排行榜

评论排行榜

//////////////////////TestClass.h
#ifndef _TEST_H_
#define _TEST_H_

class TestClass2;
class TestClass1
{
private:
       int i;
public:
       TestClass1()
       {
              i = 10;
       }

       void ChangePrivate(TestClass2& test,int change_i);

};


class TestClass2
{
private:
       int i;
public:

       TestClass2()
       {
           i = 20;
       }

       friend void TestClass1::ChangePrivate(TestClass2& test,int change_i);
};

#endif

///////////////////////////TestClass.cpp
#include "stdafx.h"
#include "TestClass.h"

void TestClass1::ChangePrivate(TestClass2& test,int change_i)
{
    test.i = change_i;
}

/////////////////////Main.cpp
#include "TestClass.h"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
 
       TestClass1 test1;
       TestClass2 test2;

       test1.ChangePrivate(test2,1);

       getchar();
       getchar();
       return 0;
}

现在我不明白的是TestClass.cpp里的
void TestClass1::ChangePrivate(TestClass2& test,int change_i)
{
    test.i = change_i;
}
我如果放在TestClass.h里面  就link错误,如果哪位仁兄能指导下不胜感激,错误提示如下:
Generating Code...
Linking...
TsetClass.obj : error LNK2005: "public: void __thiscall TestClass1::ChangePrivate(class TestClass2 &,int)" (?ChangePrivate@TestClass1@@QAEXAAVTestClass2@@H@Z) already defined in thinking test.obj
E:\随便\thinking test\Debug\thinking test.exe : fatal error LNK1169: one or more multiply defined symbols found
Build log was saved at "file://e:\随便\thinking test\thinking test\Debug\BuildLog.htm"
thinking test - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

posted on 2007-02-28 18:00 @王一伟 阅读(2076) 评论(10)  编辑 收藏 引用

Feedback

# re: friend随笔 2007-02-28 19:03 李锦俊
非模板类的函数实现不可以放在头文件中。h文件是不会被编译的。所以,
void TestClass1::ChangePrivate(TestClass2& test,int change_i)
{
test.i = change_i;
}
放在头文件中,跟完全没有写的结果是一样的。  回复  更多评论
  

# re: friend随笔 2007-02-28 19:27 万连文
上面的解释不对吧,从错误来看是重复定义而不是没定义啊,怎么和没写一样呢?至于为何有问题从上面很难看出,不过这样的代码:
friend void TestClass1::ChangePrivate(TestClass2& test,int change_i);
是否觉得有些不优雅(ugly)。  回复  更多评论
  

# re: friend随笔 2007-02-28 20:49 lusrmgr.msc
非模板类的成员函数实现如果在头文件中(除了内联),那么任何包含该头文件的 CPP 文件在编译时都为生成一个函数实体,这样在连接的时候就找到多重定义的符号。

  回复  更多评论
  

# re: friend随笔 2007-02-28 23:11 璞石
………………
如果把函数实现放在头文件里,如果头文件被多个c文件包含,当然就会产生多个实体,出错很正常。一般来说没看见这么用头文件的。  回复  更多评论
  

# re: friend随笔 2007-02-28 23:36 ;)
#ifndef
#endif

只是保证某个头文件只被某个cpp文件包含一次,避免重复"定义",但是他并不能阻止某个变量被多次"实例化"
如int g_global;不仅仅是"定义"了一个变量,同时也"实例化"了一个变量,所以,当你在头文件中包含了这个东西的时候,如果这个头文件被多个cpp文件包含,那么它将被"实例化"多次,这样就引起了冲突
同样对于一个函数,如果你在头文件中如下写
void ok()
{
}
那么,这不仅表示"定义"了这个函数,而且"实例化"了这个函数,同样也会引起冲突

网上搜索到的

不过要是在template里面的话就可以,因为template只有在用到的时候才进行实例化,而且很多编译器都不支持分开(申明和实现分开,就想你代码里的ChangePrivate函数一样),只有把实现一起放在头文件里面  回复  更多评论
  

# re: friend随笔 2007-03-01 10:16 王一伟
正如lusrmgr.msc 所说的,我
inline void TestClass1::ChangePrivate(TestClass2& test,int change_i)
{
test.i = change_i;
}
后就对了

非模板类的成员函数实现如果在头文件中(除了内联),那么任何包含该头文件的 CPP 文件在编译时都为生成一个函数实体,这样在连接的时候就找到多重定义的符号。

多谢各位的指导,可惜这里不是csdn,不然就可以给大家一些分了  回复  更多评论
  

# re: friend随笔 2007-03-01 10:31 王一伟
.h文件里面的函数,不管是成员函数还是global函数,只要不把实现写在class或者内部,貌似无法自动inline.

呵呵  回复  更多评论
  

# re: friend随笔 2007-03-04 11:26 chemz
这是一个非常基本的问题,在C/C++语言中所有的定义体都只能有一个,不能够在多个编译单元中重复出现,所以回出现重复定义的问题,要解决这个问题可以采用内联的方式解决,而C++中可以采用隐式内联和显示内联两种方式,隐式内联就是写在类的申明中,显示内联就是在声明和定义出添加inline关键字.
  回复  更多评论
  

# re: friend随笔 2007-03-04 16:47 酱菜
多谢chemz兄的总结 很精辟  回复  更多评论
  

# re: friend随笔 2007-03-31 15:50 青儿~Lv
?????????????????看这个我还是去看天书好了~~~~~可以留言了~~嘿嘿  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理