gpt4 book ai didi

c++ - RVO/NRVO 和公共(public)未定义复制构造函数

转载 作者:可可西里 更新时间:2023-11-01 16:37:06 30 4
gpt4 key购买 nike

我现在正在反对以下提议,我想知道反对或支持它的法律和较小程度上的道德论据。

我们有什么:

#include <vector>

class T;

class C
{
public:
C() { }
~C( ) { /*something non-trivial: say, calls delete for all elements in v*/ }
// a lot of member functions that modify C
// a lot of member functions that don't modify C
private:
C(C const &);
C& operator=(C const&);
private:
std::vector< T* > v;
};

void init(C& c) { } // cannot be moved inside C

// ...
int main()
{
// bad: two-phase initialization exposed to the clients
C c;
init(c);

// bad: here follows a lot of code that only wants read-only access to c
// but c cannot be declared const
}

提出了什么:

#include <vector>

class T;

class C
{
public:
C() { }
~C( ) { /*calls delete for all elements in v*/ }

// MADE PUBLIC
C(C const &); // <-- NOT DEFINED

// a lot of member functions that modify C
// a lot of member functions that don't modify C
private:
C& operator=(C const&);
private:
vector< T* > v;
};

C init() // for whatever reason object CANNOT be allocated in free memory
{
C c;
// init c
return c;
}

// ...
int main()
{
C const & c = init();
}

这使用最近的 g++(它是唯一的目标编译器)4.1.2 和 4.4.5 编译和链接(和工作)——因为 (N)RVO,永远不会调用复制构造函数;析构函数仅在 main() 结束时调用。

据说这项技术非常好,因为复制构造函数不可能被误用(如果它曾经被生成,那将是链接器错误),并且将其公开可以防止编译器提示私有(private)一个。

我使用这样的技巧看起来真的非常错误,我觉得这与 C++ 精神相矛盾,看起来更像是 hack —— 从这个词的糟糕意义上来说。

我的感觉不足以论证,所以我现在正在寻找技术细节。

请不要在这里发布教科书 C++ 内容:

  • 我了解“三法则”并已通读 Holy Standard 的 12.8/15 和 12.2;
  • 我都不能用 vector<shared_ptr<T> >也不ptr_vector<T> ;
  • 我无法分配 C在可用内存中并从 init 返回它通过C* .

谢谢。

最佳答案

This compiles and links (and works) using recent g++ (which is the only target compiler) both 4.1.2 and 4.4.5 -- because of (N)RVO the copy-constructor is never called; destructor is called at the end of main() only.

虽然它可能适用于 GCC,但您的代码确实具有未定义的行为,因为它引用了未定义的函数。在这种情况下,您的程序格式错误;无需诊断。这意味着 GCC 可能会忽略规则违规,但其他编译器可能会诊断它或做一些其他奇怪的事情。

所以基于这些理由,我会拒绝这种方式。

My feelings is not sufficient argumentation, so I'm looking for technicalities now.

你想在这里有移动语义。明确这一点怎么样?

class T;
class C;

struct CMover {
C *c;
private:
CMover(C *c):c(c) { }
friend CMover move(C &c);
};

class C {
public:
C() { }
~C( ) { /*calls delete for all elements in v*/ }

C(CMover cmove) {
swap(v, cmove.c->v);
}

inline operator CMover();

// a lot of member functions that modify C
// a lot of member functions that don't modify C
private:
C& operator=(C const&); // not copy assignable
C(C &); // not lvalue copy-constructible

private:
vector< T* > v;
};

CMover move(C &c) { return CMover(&c); }
C::operator CMover() { return move(*this); }

现在你可以说

C init() // for whatever reason object CANNOT be allocated in free memory
{
C c;
return move(c);
}

int main() {
C const c(init());
}

关于c++ - RVO/NRVO 和公共(public)未定义复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5552981/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com