2012-12-14 56 views
2

只是阅读关于朋友函数,我试图从类B访问类A中的私有变量“number”和朋友函数“Print”。我正在使用Visual Studio。我的代码编译给了我大量的各种错误,如:在C++中使用朋友函数

C2011: 'A': '类' 类型的重新定义
C2653: 'B':不是类或命名空间名称

请耐心等待我,并展示实现我目标的正确方法。

这里是我的文件 A.H:

class A 
{ 
public: 
    A(int a); 
    friend void B::Print(A &obj); 
private: 
    int number; 
}; 

A.cpp:

#include "A.h" 

A::A(int a) 
{ 
    number=a; 
} 

B.h:

#include <iostream> 
using namespace std; 
#include "A.h" 
class B 
{ 
public: 
    B(void); 
    void Print(A &obj); 
}; 

B.cpp:

#include "B.h" 

B::B(void){} 

void B::Print(A &obj) 
{ 
    cout<<obj.number<<endl; 
} 

main.cpp中:

#include <iostream> 
#include <conio.h> 
#include "B.h" 
#include "A.h" 

void main() 
{ 
    A a_object(10); 
    B b_object; 
    b_object.Print(A &obj); 
    _getch(); 
} 
+2

提示:类'B'实际上并不需要知道'A'的细节,它只需要知道类A'_exists_。 –

+0

删除'friend void B :: Print(A &obj);',加上'friend class B;'或者跟随Mooning Ducks tip。 – andre

+0

在Bh删除 '#include“啊”' 并加上 'class A;'然后add '#include“Ah”'in B.cpp – Ben

回答

1

首先,你需要把

#ifndef A_H 
#define A_H 
.... your A-class definition 
#endif 

你丫和波黑类似,以便多个包含相同的文件被阻止(这是你重复定义错误)...

+1

或者你可以在你的.h文件开头加上“#pragma once” – PRouleau

+1

不,请删除双下划线。包含两个下划线和以下划线开头并带有大写字母的名称的名称保留给实施。不要使用它们。 –

+0

@PRouleau - 不在可移植代码中。 –

3

...其次,你可能需要B类的前向声明在A.h头文件指B为好友:

#ifndef _A_H_ 
#define _A_H_ 
class B; 

class A 
{ 
    friend class B; 
}; 
#endif 

UPDATE
我目前并不确定是否有可能宣布的成员函数作为朋友,我要看看。

无法创建成员函数friend声明,您可以声明全局函数或整个类作为朋友,另请参阅:C++ ref, Friendship and inheritance

一般来说,使用friend完全不是一个好的设计理念,因为它强烈地将这些类连接在一起。更好的解决方案将是耦合接口(不需要公开可见)。
在极少数情况下,它可能是一个很好的设计决策,但几乎总是适用于内部细节。

+1

使用'朋友'并不总是不好。见http://www.parashift.com/c++-faq/friends-and-encap.html –

+0

@FredLarson是的,我提到了弗雷德。无论如何,它已经在UML中被弃用了,并且通常可以使用抽象(纯虚拟)或静态(模板)接口替换对“朋友”声明的需要。这也可以让你精确控制“朋友”类或方法可以访问的内容。 –