你们其中一个人可以解释为什么下面这段代码不能编译吗?
#include <iostream>
using namespace std;
class Foo
{
public:
Foo() { cout << "Foo::Foo()" << endl << endl; }
Foo& operator=(const Foo&) { cout << "Foo::operator=(const Foo&)" << endl << endl; }
private:
Foo(const Foo& b) { *this = b; cout << "Foo::Foo(const Foo&)" << endl << endl; }
};
int main()
{
Foo foo;
foo = Foo();
}
Run Code Online (Sandbox Code Playgroud)
我收到的错误:
$ g++ -o copy_ctor_assign copy_ctor_assign.cc && ./copy_ctor_assign
copy_ctor_assign.cc: In function 'int main()':
copy_ctor_assign.cc:10: error: 'Foo::Foo(const Foo&)' is private
copy_ctor_assign.cc:17: …Run Code Online (Sandbox Code Playgroud) 有没有办法让我可以使复制构造函数和赋值运算符的主体包含相同的代码,而实际上没有重复的代码(函数头除外)?
c++ constructor code-duplication copy-constructor assignment-operator
有没有办法允许移动构造函数并禁止复制构造和赋值.我可以想到几个带有文件指针和缓冲区指针(资源句柄等)的类,这些类可以从复制构造和分配中受益.
我使用的是VC2010和GCC 4.5.2.我知道我必须在VC2010类头中声明空的私有赋值和复制构造函数,据我所知,GCC允许在方法之后执行相同的操作时使用某种删除签名.
如果有人有这样一个骨架类的好例子和优点,我将非常感激.在此先感谢约翰
这是一个我希望允许移动的类的示例,但我还想阻止直接分配.这是复制构造函数和operator = private的问题吗?
class LoadLumScanner_v8002 : public ILoadLumScanner {
public:
// default constructor
LoadLumScanner_v8002();
// copy constructor
LoadLumScanner_v8002(const LoadLumScanner_v8002& rhs);
// move constructor
LoadLumScanner_v8002(LoadLumScanner_v8002&& rhs);
// non-throwing copy-and-swap idiom unified assignment
inline LoadLumScanner_v8002& operator=(LoadLumScanner_v8002 rhs) {
rhs.swap(*this);
return *this;
}
// non-throwing-swap idiom
inline void swap(LoadLumScanner_v8002& rhs) throw() {
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// swap base members
// ...
// swap members
swap(mValidatedOk, rhs.mValidatedOk);
swap(mFile, rhs.mFile);
swap(mPartNo, …Run Code Online (Sandbox Code Playgroud) 在我看来应该有四种变体 boost::optional
optional<Foo> =>持有一个可变的Foo,可以在初始化后重新分配
optional<Foo const> const =>持有一个const Foo,初始化后无法重新分配
optional<Foo> const =>(应该?)保持一个可变的Foo,但在初始化后不能重新分配
optional<Foo const> =>(应该?)持有一个const Foo,可以在初始化后重新分配
前2个案例按预期工作.但是对optional<Foo> constconst Foo 的解引用,并且optional<Foo const>在初始化之后不允许重新分配(如本问题所述).
const值类型的重新分配是我遇到的具体内容,错误是:
/usr/include/boost/optional/optional.hpp:486:错误:使 'const的富' 为 '这个' 的参数 '富&富::运算符=(const的富&)' 丢弃限定符[-fpermissive]
它发生在这里:
void assign_value(argument_type val,is_not_reference_tag) { get_impl() = val; }
Run Code Online (Sandbox Code Playgroud)
构造之后,实现使用赋值运算符作为参数化可选的类型.它显然不希望左手操作数是一个const值.但是为什么不能将非const可选项重置为新的const值,例如在这种情况下:
optional<Foo const> theFoo (maybeGetFoo());
while (someCondition) {
// do some work involving calling some methods on theFoo
// ...but they should only be const ones
theFoo = maybeGetFoo();
}
Run Code Online (Sandbox Code Playgroud)
一些问题:
我是否正确,希望这在概念上很好,而且无法做到这只是实施中的侥幸?
如果我不编辑boost源,那么在上面的循环中实现逻辑的干净方法是什么,而不是完全废弃boost :: optional?
如果这确实有意义并且我要编辑boost …
c++ boost const-correctness assignment-operator boost-optional
在C#中这样做是否安全?
field = Property = value;
Run Code Online (Sandbox Code Playgroud)
是否保证连续调用setter和getter并且field只分配getter的结果而不一定value?编译器会优化它value吗?
尝试使简单的代码工作:
std::thread threadFoo;
std::thread&& threadBar = std::thread(threadFunction);
threadFoo = threadBar; // thread& operator=( thread&& other ); expected to be called
Run Code Online (Sandbox Code Playgroud)
得到错误:
使用已删除的函数'std :: thread&std :: thread :: operator =(const std :: thread&)'
我明确地定义threadBar为右值引用,而不是普通引用.为什么没有预期的操作员被调用?如何将一个线程移动到另一个线程?
谢谢!
我正在阅读关于raw_storage_iterator组件的TC++ PL .使用此组件可以获得性能优势,因为它可以避免分配(更昂贵)并使用复制构造.在我看来它应该在序列/容器中使用,在那里我们可以有大量的元素,因此赋值调用的数量可能会产生很大的影响.
理论上它很明确,它在我看来这个组件对容器类型类很有用.但是,我想了解我们应该在位详细信息中使用此组件(带有实际示例)以获得其性能优势?
如果我们将复制构造函数和赋值运算符设置为私有并且不提供任何实现,则它们将被禁用,如下所示:
class Test
{
priavate:
Test(const Test&);
Test& operator=(const Test&);
};
Run Code Online (Sandbox Code Playgroud)
但在这种情况下我们需要这样做?我的意思是我们什么时候应该这样做?
当我尝试在Visual Studio 2015中编译以下最小示例时,我遇到了误导性错误消息的问题:
class Vector
{
float x;
float y;
public:
Vector(float x, float y) : x(x), y(y) {}
Vector& operator = (const Vector& v) { x = v.x; y = v.y; return *this; }
//Vector(Vector&&) = default;
};
class Rect
{
public:
union {
struct {
Vector p1, p2;
};
struct {
float p1x, p1y, p2x, p2y;
};
};
Rect() : p1(0,0), p2(0,0) {}
Rect(Vector& p1, Vector& p2) : p1(p1), p2(p2) {}
/*Rect(const Rect&) = default;
Rect& operator=(const Rect&) …Run Code Online (Sandbox Code Playgroud) 我经常需要为“原始”资源句柄(例如文件句柄,Win32 OS句柄等)实现C ++包装。这样做时,我还需要实现move运算符,因为默认的编译器生成的操作符不会清除move-from对象,从而产生双删除问题。
在实现移动分配运算符时,我更喜欢显式调用析构函数,并使用new放置就地重新创建对象。这样,我避免了析构函数逻辑的重复。另外,我经常根据copy + move(在相关时)实现副本分配。这将导致以下代码:
/** Canonical move-assignment operator.
Assumes no const or reference members. */
TYPE& operator = (TYPE && other) noexcept {
if (&other == this)
return *this; // self-assign
static_assert(std::is_final<TYPE>::value, "class must be final");
static_assert(noexcept(this->~TYPE()), "dtor must be noexcept");
this->~TYPE();
static_assert(noexcept(TYPE(std::move(other))), "move-ctor must be noexcept");
new(this) TYPE(std::move(other));
return *this;
}
/** Canonical copy-assignment operator. */
TYPE& operator = (const TYPE& other) {
if (&other == this)
return *this; // self-assign
TYPE copy(other); // may throw
static_assert(noexcept(operator …Run Code Online (Sandbox Code Playgroud) c++ assignment-operator move-semantics move-assignment-operator
c++ ×9
c++11 ×3
.net ×1
boost ×1
c# ×1
constructor ×1
performance ×1
private ×1
properties ×1
struct ×1
unions ×1