标签: assignment-operator

C++的异常安全隐式生成赋值运算符

我的理解是C++ 隐式生成的赋值运算符执行成员方式的复制(这似乎也得到了这个答案的证实).但是,如果在成员副本期间抛出异常(例如,因为无法分配该成员的资源),被复制的对象是否会陷入无效状态?

换句话说,隐式生成的赋值运算符是仅实现基本保证,而不是强保证?

如果我们想要为我们的类副本提供强有力的保证,我们是否必须使用copy-and-swap惯用法手动实现赋值运算符?

c++ exception assignment-operator exception-safety

15
推荐指数
1
解决办法
1052
查看次数

如果成员具有非平凡的noexcept赋值运算符,则默认的移动赋值不能明确地为noexcept

此代码无法使用gcc 4.8.2(-std = c ++ 11)进行编译,但使用clang 3.4(trunk)编译(-std = c ++ 11):

#include <type_traits>
#include <vector>

struct X {
  X& operator=(X&&) noexcept = default;
  // adding noexcept this leads to an error in gcc, but works in clang:
  // function ‘X& X::operator=(X&&)’ defaulted on its first
  // declaration with an exception-specification that differs from the
  // implicit declaration ‘X& X::operator=(X&&)’

  std::vector<char> m;
};

// this assert holds, even without noexcept
static_assert(std::is_nothrow_move_assignable<X>::value, 
              "type-specification violation");

int main()
{
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

static_assert …

c++ assignment-operator move-semantics c++11

15
推荐指数
1
解决办法
2178
查看次数

在C++ 11中"删除"复制ctor/assignment

在VS 2010 SP1中,以下内容:

class Foo
{
public:
    Foo() { }
    Foo(Foo const&) = delete; // Line 365
    Foo& operator=(Foo const&) = delete; // Line 366
};
Run Code Online (Sandbox Code Playgroud)

不编译.它抱怨说:

CPPConsole.cpp(365):错误C2059:语法错误:';'
CPPConsole.cpp(365):错误C2238:';'之前的意外标记
CPPConsole.cpp(366):错误C2059:语法错误:';'
CPPConsole.cpp(366):错误C2238:';'之前的意外令牌

这不支持吗?奇怪的是,Intellisense似乎认识到这种结构.它说"IntelliSense:function"Foo :: operator =(const Foo&)"(在第366行声明)无法引用 - 它是一个已删除的函数"

我错过了什么?

copy-constructor assignment-operator c++11

14
推荐指数
1
解决办法
1万
查看次数

为什么派生类不使用基类operator =(赋值运算符)?

以下是实际问题的简化版本.Base::operator=(int)代码似乎不是调用,而是生成临时Derived对象并复制它.为什么不使用基本赋值运算符,因为函数签名似乎完全匹配?这个简化的示例没有显示任何不良影响,但原始代码在析构函数中具有副作用,导致各种破坏.

#include <iostream>
using namespace std;

class Base
{
public:
   Base()
   {
      cout << "Base()\n";
   }

   Base(int)
   {
      cout << "Base(int)\n";
   }

   ~Base()
   {
      cout << "~Base()\n";
   }

   Base& operator=(int)
   {
      cout << "Base::operator=(int)\n";
      return *this;
   }
};

class Derived : public Base
{
public:
   Derived()
   {
      cout << "Derived()\n";
   }

   explicit Derived(int n) : Base(n)
   {
      cout << "Derived(int)\n";
   }

   ~Derived()
   {
      cout << "~Derived()\n";
   }
};

class Holder
{
public:
   Holder(int n)
   {
      member …
Run Code Online (Sandbox Code Playgroud)

c++ operator-overloading assignment-operator

14
推荐指数
1
解决办法
956
查看次数

我应该为赋值运算符使用左值引用限定符吗?

最近,我跟着讨论了C++中表达式的赋值,如下例所示:

string s1, s2, s3;
(s1 + s2) = s3;
Run Code Online (Sandbox Code Playgroud)

使用C++ 11,可以将赋值运算符限制为左值引用(在左侧).当声明赋值运算符如下时,由于类型不兼容,编译器Clang拒绝带有错误消息的代码.

auto operator=(const string& rhs) & -> string&;
auto operator=(string&& rhs) & -> string&;
Run Code Online (Sandbox Code Playgroud)

我没有在任何地方见过这个.是否有充分的理由不为赋值运算符使用左值引用限定符(除了在大多数编译器中缺少支持)?

c++ operator-overloading assignment-operator c++11

14
推荐指数
2
解决办法
1215
查看次数

Swift分配评估失效的原因是什么?

这个问题是关于历史(不是你目前对此事的看法).

在阅读关于为Swift删除对递增/递减运算符的支持的帖子时,我读了这样的文本"Swift已经偏离C,因为=,+ =和其他类似赋值的操作返回Void(由于多种原因)".

所以在过去的某个时候,开发人员有意识地决定将任务评估为无效,原因有些.

我正在寻找那些历史(现在)的原因.就像这个线程是关于Scala的历史原因一样.

language-design assignment-operator swift

14
推荐指数
1
解决办法
623
查看次数

为什么析取赋值运算符| =不适用于bool向量?

如果我有一个,vector<bool> vec_bool那么我无法使用|=赋值运算符修改向量的内容.就是这条线

vec_bool[0] |= true;
vec_bool[0] |= vec_bool[1];
Run Code Online (Sandbox Code Playgroud)

给出编译错误,而行

bool a = false;
a |= true;
a |= vec_bool[0];
vec_bool[0] = vec_bool[0] | vec_bool[1];
vec_bool[0] = vec_bool[0] || vec_bool[1];

vector<int> vec_int(3);
vec_int[0] |= vec_int[1];
Run Code Online (Sandbox Code Playgroud)

不要.这是什么原因?

给出的错误(通过gcc)是:

TEST.CPP:21:17:错误:不对应的 '运营商| ='(操作数的类型是 '的std ::矢量::参考{又名的std :: _ Bit_reference}' 和 '布尔')

c++ assignment-operator

14
推荐指数
1
解决办法
857
查看次数

从复制构造函数调用默认赋值运算符是不好的形式?

考虑一类需要复制的副本.副本中的绝大多数数据元素必须严格反映原始数据元素,但是有少数元素的状态不被保留且需要重新初始化.

从复制构造函数调用默认赋值运算符是不好的形式?

默认赋值运算符对于Plain Old Data(int,double,char,short)以及每个赋值运算符的用户定义类都表现良好.指针需要单独处理.

一个缺点是该方法使得赋值运算符瘫痪,因为不执行额外的重新初始化.也无法禁用赋值运算符的使用,从而通过使用不完整的默认赋值运算符打开用户创建损坏类的选项A obj1,obj2; obj2=obj1; /* Could result is an incorrectly initialized obj2 */.

a(orig.a),b(orig.b)...除了a(0),b(0) ...必须写之外,放宽要求是很好的.需要写入所有初始化两次会产生两个错误位置,如果double x,y,z要将新变量(例如)添加到类中,初始化代码需要在至少2个位置而不是1个位置正确添加.

有没有更好的办法?

在C++ 0x中有更好的方法吗?

class A {
  public:
    A(): a(0),b(0),c(0),d(0)
    A(const A & orig){
      *this = orig;       /* <----- is this "bad"? */
      c = int();
    }
  public:
    int a,b,c,d;
};

A X;
X.a = 123;
X.b = 456;
X.c = 789;
X.d = 987;

A Y(X);

printf("X: %d %d %d %d\n",X.a,X.b,X.c,X.d); …
Run Code Online (Sandbox Code Playgroud)

c++ constructor copy-constructor assignment-operator c++11

13
推荐指数
2
解决办法
4698
查看次数

分配操作员 - 自我分配

编译器是否为自我赋值生成了赋值操作符?

class T {

   int x;
public:
   T(int X = 0): x(X) {}
};

int main()
{
   T a(1);
   a = a;
}
Run Code Online (Sandbox Code Playgroud)

即使班级成员不是指针类型,我是否总是需要防止自我分配?

c++ assignment-operator

13
推荐指数
2
解决办法
6478
查看次数

我认为数组是不可复制的

我的印象是阵列是不可复制的(或可分配的).

int x[5] = {1,2,3,4,5};
int y[5] = {6,7,8,9,0};

x = y; // Fails to compile
Run Code Online (Sandbox Code Playgroud)

但是当我在一个类中放入一个数组时,复制构造函数和赋值运算符工作(我会按预期说,但它不是我所期望的).

#include <iostream>

struct X
{
    virtual ~X(){} // Just in case it was something to do with POD 
                   // make sure its not a POD
    int x[5];
};

int main()
{
    X   a;

    a.x[0]  = 0;
    a.x[1]  = 1;
    a.x[2]  = 2;
    a.x[3]  = 3;
    a.x[4]  = 4;

    // Make a copy of a and test it
    X   b(a);          
    std::cout << a.x[0] << …
Run Code Online (Sandbox Code Playgroud)

c++ arrays copy-constructor assignment-operator

13
推荐指数
1
解决办法
690
查看次数