C++对不同功能的私有嵌套访问
C++ private nested access to different functions
发现这种奇怪的编译行为,在VS2012,VS2017和 https://www.onlinegdb.com/online_c++_compiler 上进行了检查(
基本上,对于私有嵌套类,您可以在外部调用公共函数,但不能调用公共构造函数。
3个问题:
-
编译器让我调用 func(( 背后的原因是什么?
-
如果编译器允许我调用 func((,为什么我不能调用 ctor?
-
如果我不能打电话给CTOR,emplace_back怎么能做到呢?
class Outer {
struct PrivateInner {
PrivateInner() {}
void func() {}
};
public:
PrivateInner inner;
std::vector<PrivateInner> innerVect;
};
void f1()
{
Outer c;
c.inner.func(); // COMPILING, but why?
}
void f2()
{
Outer c;
c.innerVect.push_back(Outer::PrivateInner()); // NOT COMPILING, why no access to ctor if there is access to func()?
c.innerVect.emplace_back(); // COMPILING, but why? Doesn't it call Outer::PrivateInner inside?
}
如我所见,我仍然可以创建一个(静态(函数createObject((:
class Outer {
struct PrivateInner {
PrivateInner() {}
static PrivateInner createObject() { return PrivateInner(); }
void func() {}
};
.....
};
然后调用它。
createObject(( 可能是非静态的,如果从实例调用 static 不是纯粹的标准。
c.innerVect.push_back(c.inner.createObject()); // COMPILING
"破解"编译
注意嵌套的struct
PrivateInner
被声明为private
,所以只有Outer::PrivateInner
是private
的,没有足够的访问权限,你不能用这个名称来声明像Outer::PrivateInner pi;
这样的变量,但你可以像decltype(Outer::inner) pi;
一样写。
另一方面,它的构造函数和成员函数是public
的,所以它们可以被调用。
c.inner.func(); // COMPILING, but why?
func()
是public
,所以如果你有一个类型Outer::PrivateInner
的实例,你可以在它上面调用func
。
c.innerVect.push_back(Outer::PrivateInner()); // NOT COMPILING, why no access to ctor if there is access to func()?
它与构造函数无关,您只是不能在此处使用Outer::PrivateInner
的名称。
c.innerVect.emplace_back(); // COMPILING, but why? Doesn't it call Outer::PrivateInner inside?
构造函数是public
的,然后可以用来构造对象。 std::vector
不会像Outer::PrivateInner
那样直接使用名称;它使用指定为模板参数的名称。
顺便说一句:出于同样的原因,
c.innerVect.push_back(c.inner.createObject()); // COMPILING
但c.innerVect.push_back(Outer::PrivateInner::createObject());
不会编译。
成员是公共的,因此您当然可以调用其成员函数。如果它的名字是可见的,那么它自己的公共成员也是可见的。
同样,内部类是私有的,因此您当然不能从类外部引用其名称。这些是访问控制规则的基本定义。
emplace_back
可以调用构造函数,因为std::vector
从允许引用它的人那里收到了该类型作为模板参数。实例化模板时发生访问检查。那时它的名字是可以访问的。
您可以使用 decltype
在类外部的任何地方调用构造函数:
Outer c;
auto this_works_too = decltype(c.inner){};
这是有效的,因为您不必使用无法访问的名称来引用它。
访问控制应用于名称。这意味着只有struct
PrivateInner
的名称受到限制。struct
本身的成员有自己的访问控制。所以PrivateInner
的所有成员都是公开的。
11 成员访问控制 [类访问]
1 类的成员可以是
- private;也就是说,它的名称只能由声明它的类的成员和朋友使用。
。
4 访问控制统一应用于所有名称,无论名称 从声明或表达式中引用。...
正如您已经发现的那样,如果您不使用构造函数的名称,则可以使用构造函数(以及一般的struct
(:
c.innerVect.push_back({});
c.innerVect.emplace_back();
甚至
template <typename T>
T createPrivateInner()
{
return T();
}
...
c.innerVect.push_back(createPrivateInner<decltype(Outer::inner)>());
成员 "createObject((" 是私有的。因此,当然,您无法访问它。您应该在公共字段中添加一些成员函数来实现此私有成员。
- 无法访问嵌套类.类的使用无效
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- C++将结构传递给函数以访问嵌套结构
- 嵌套容器:为什么我无法访问堆栈队列顶部的堆栈?C++
- 通过 id 访问 QML 插槽中的嵌套对象(从 c++ 调用)
- 如何访问嵌套类的数据?
- 访问另一个类中的模板化嵌套类函数和对象
- 如何访问嵌套在命名命名空间中的未命名命名空间变量?
- 优雅地访问嵌套类中的数据
- 无法从多态嵌套类访问包含类的成员
- 嵌套的类成员变量不可访问.链表设置.V、下一个和新的问题
- 访问range_expression中的嵌套元素会返回不完整的映射(段错误)
- 如何通过迭代器访问向量中的嵌套对?
- 在 c++ 中访问嵌套字典unordered_map<字符串、void*>?
- Python和Ctypes访问带有嵌套结构的C 类
- 为什么 clang 不允许通过实例访问嵌套枚举类?
- 访问嵌套块中重新定义的变量
- C++对不同功能的私有嵌套访问
- 通过指向成员的指针对嵌套访问进行编译时评估期间出现 GCC 错误