全局命名空间朋友 class 无法访问命名空间 class 的私有成员
Global namespace friend class cannot access private member of named namespace class
在命名空间 class 中,我将 class(在全局空间中)声明为友元。
但是,后者class无法访问前者class的私有成员。为什么是这样?有什么解决办法吗?
Bob.h
namespace ABC {
class Bob {
friend class Joe;
public:
Bob ();
int pub_number;
private:
int priv_number;
};
}
Bob.cc
#include "Bob.h"
ABC::Bob::Bob () {
pub_number=10;
priv_number=6;
}
Joe.h
class Joe {
Joe ( );
};
Joe.cc
#include "Joe.h"
#include <iostream>
#include "Bob.h"
Joe::Joe ( ) {
ABC::Bob b;
std::cout << b.pub_number << std::endl;
std::cout << b.priv_number << std::endl;
}
以上代码在编译时产生如下错误:
Joe.cc:8:16: error: ‘int ABC::Bob::priv_number’ is private within this context
INFO: 1> 8 | std::cout << b.priv_number << std::endl;
如果我执行与上面相同的代码,但没有为“Bob”class 命名空间,则代码可以编译。
我已尝试在 Bob.h 中转发声明乔 class 如下:
class Joe; // This does nothing to help
class ::Joe // This produces compiler message "error: ‘Joe’ in namespace ‘::’ does not name a type"
您的 friend
声明也需要 ::
前缀:
class Joe;
namespace ABC {
class Bob {
friend class ::Joe;
// ^^ here
...
};
}
您需要在全局命名空间中添加无作用域的前向声明,并在声明友元时使用作用域运算符:
class Joe; // Forward declaration
namespace ABC {
class Bob {
friend class ::Joe; // Use the Joe class from the global scope
public:
Bob ();
int pub_number;
private:
int priv_number;
};
}
在此class定义中
namespace ABC {
class Bob {
friend class Joe;
public:
Bob ();
int pub_number;
private:
int priv_number;
};
}
朋友 class Joe
的声明在命名空间 ABC
的范围内引入了名称 Joe
因为 class 的先前声明Joe
不可见,使用了不合格的名称。
来自 C++ 标准(10.3.1.2 命名空间成员定义)
- ... If the name in a friend declaration is neither qualified nor a
template-id and the declaration is a function or an
elaborated-type-specifier, the lookup to determine whether the entity
has been previously declared shall not consider any scopes outside the
innermost enclosing namespace.
您需要在 class Bob
的声明之前和 class 中的全局命名空间中放置 class Joe
的声明Bob
你必须使用朋友的合格名称 class 至少喜欢
class Joe;
namespace ABC {
class Bob {
friend class ::Joe;
public:
Bob ();
int pub_number;
private:
int priv_number;
};
}
或者您可以在命名空间 ABC
中使用 using 声明,例如
class Joe;
namespace ABC {
using ::Joe;
class Bob {
friend class Joe;
public:
Bob ();
int pub_number;
private:
int priv_number;
};
}
在命名空间 class 中,我将 class(在全局空间中)声明为友元。 但是,后者class无法访问前者class的私有成员。为什么是这样?有什么解决办法吗?
Bob.h
namespace ABC {
class Bob {
friend class Joe;
public:
Bob ();
int pub_number;
private:
int priv_number;
};
}
Bob.cc
#include "Bob.h"
ABC::Bob::Bob () {
pub_number=10;
priv_number=6;
}
Joe.h
class Joe {
Joe ( );
};
Joe.cc
#include "Joe.h"
#include <iostream>
#include "Bob.h"
Joe::Joe ( ) {
ABC::Bob b;
std::cout << b.pub_number << std::endl;
std::cout << b.priv_number << std::endl;
}
以上代码在编译时产生如下错误:
Joe.cc:8:16: error: ‘int ABC::Bob::priv_number’ is private within this context
INFO: 1> 8 | std::cout << b.priv_number << std::endl;
如果我执行与上面相同的代码,但没有为“Bob”class 命名空间,则代码可以编译。
我已尝试在 Bob.h 中转发声明乔 class 如下:
class Joe; // This does nothing to help
class ::Joe // This produces compiler message "error: ‘Joe’ in namespace ‘::’ does not name a type"
您的 friend
声明也需要 ::
前缀:
class Joe;
namespace ABC {
class Bob {
friend class ::Joe;
// ^^ here
...
};
}
您需要在全局命名空间中添加无作用域的前向声明,并在声明友元时使用作用域运算符:
class Joe; // Forward declaration
namespace ABC {
class Bob {
friend class ::Joe; // Use the Joe class from the global scope
public:
Bob ();
int pub_number;
private:
int priv_number;
};
}
在此class定义中
namespace ABC {
class Bob {
friend class Joe;
public:
Bob ();
int pub_number;
private:
int priv_number;
};
}
朋友 class Joe
的声明在命名空间 ABC
的范围内引入了名称 Joe
因为 class 的先前声明Joe
不可见,使用了不合格的名称。
来自 C++ 标准(10.3.1.2 命名空间成员定义)
- ... If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.
您需要在 class Bob
的声明之前和 class 中的全局命名空间中放置 class Joe
的声明Bob
你必须使用朋友的合格名称 class 至少喜欢
class Joe;
namespace ABC {
class Bob {
friend class ::Joe;
public:
Bob ();
int pub_number;
private:
int priv_number;
};
}
或者您可以在命名空间 ABC
中使用 using 声明,例如
class Joe;
namespace ABC {
using ::Joe;
class Bob {
friend class Joe;
public:
Bob ();
int pub_number;
private:
int priv_number;
};
}