【发布时间】:2025-12-19 07:35:06
【问题描述】:
好吧,我有一个小问题要解决我的问题(也许还有其他问题 ^^)。所以让我们在 C++ 中假设以下内容:
class A {
public:
A() { }
A(const A& src) { }
};
class B {
public:
B() { }
void foo(A valuePassing) { }
};
int main(int argc, char* argv[])
{
A passed;
B obj;
obj.foo(passed);
return EXIT_SUCCESS;
}
在这段代码中,谁负责调用A的copy constructor?问题可以概括为:当按值传递时,谁负责变量的副本,调用者还是被调用者?在这种特定情况下,B 会在接收到 var 时调用复制构造函数,还是 main() 会调用它并将副本发送到 B 的方法?
我的第一个想法是,为了维护由 C++ 可访问性引起的保护,应该由调用者来完成复制工作。但我需要确定这一点。每个编译器都通用吗(不明白为什么不,但编译器之间的差异有时很奇怪)?即VC++和gcc。
提前感谢您的回答;)
编辑:
如果有人想知道,这是关于实现由Georg Fritzsche 创建的Pass Key pattern。事实上,正如一些人所说,使其不可复制是一个好主意,以防止不太聪明的开发人员创建一个函数,将密钥提供给来自被授予密钥的类的任何人。但是使其不可复制也可以防止标准值参数传递(至少应该如此,我发现 Visual C++ 编译器不遵循标准并且实际上可以接受...)
我解决问题的想法是创建一个基类PassKey,它具有受保护的复制构造函数和赋值运算符。然后每个PassKey 类都将从这个类继承。然后需要使用密钥的函数通过 value 请求密钥作为第一个参数。这样,即使 smartass 开发人员执行前面提到的功能并提供对密钥的引用,尝试使用它的外部类也将无法使用它,因为它需要访问密钥的 copy constructor,它只能访问受保护和授予的类。
我说得够清楚还是需要澄清一下? :S
【问题讨论】:
-
这种差异会有任何明显的影响吗?当然,最重要的是,在某个时候,会制作一份副本。
-
你说的“谁”是什么意思?编译器在
main的上下文中插入对复制构造函数的调用。必须在调用函数之前初始化参数。 -
我想调用代码导致通过调用函数并传递
passed来发生复制,但询问什么是“负责”并没有真正意义.如果有的话,参数的初始化负责它。 -
内联使问题变得复杂,在这个特定的代码中,甚至可能没有是对
B::foo的“调用”。复制可能仍然会发生,但是如果函数是内联的,你怎么说“谁”做的呢? -
既不是调用者也不是被调用者。编译器。都夸编译器
标签: c++