相关疑难解决方法(0)

在Visual Studio 2013和2015中,C++编译器错误C2280"尝试引用已删除的函数"

在Visual Studio 2013(版本12.0.31101.00 Update 4)中编译此代码段时没有错误

class A
{
public:
   A(){}
   A(A &&){}
};

int main(int, char*)
{
   A a;
   new A(a);
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

虽然它在Visual Studio 2015 RC(版本14.0.22823.1 D14REL)中使用此错误进行编译:

1>------ Build started: Project: foo, Configuration: Debug Win32 ------
1>  foo.cpp
1>c:\dev\foo\foo.cpp(11): error C2280: 'A::A(const A &)': attempting to reference a deleted function
1>  c:\dev\foo\foo.cpp(6): note: compiler has generated 'A::A' here
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Run Code Online (Sandbox Code Playgroud)

我认为Visual Studio 2015附带的编译器生成了复制构造函数并将其标记为=delete,因此我得到了错误C2280(顺便说一句,我在msdn.microsoft.com上找不到文档).

现在,假设我有一个可与Visual Studio 2013兼容的代码库(它可以工作,因为它依赖于编译器自动生成的代码)但由于C2280而无法与Visual Studio …

c++ copy-constructor visual-c++ c++14

29
推荐指数
5
解决办法
6万
查看次数

为什么析构函数会禁用隐式移动方法的生成?

我试着通过阅读这篇博客来了解零的规则.IMO,它说如果你声明自己的析构函数,那么不要忘记创建移动构造函数并将赋值移动为默认值.

示例:

class Widget {
public:
  ~Widget();         // temporary destructor
  ...                // no copy or move functions
};
Run Code Online (Sandbox Code Playgroud)

"添加析构函数会产生禁用生成移动函数的副作用,但由于Widget是可复制的,因此用于生成移动的所有代码现在都会生成副本.换句话说,向类中添加析构函数可能会导致 - 有效的动作可以用可能效率低下的副本无声地替换".

Scott Meyers的上述文字在引言中提出了一些问题:

  • 为什么声明析构函数会隐藏移动语义?
  • 声明/ definig析构函数只隐藏移动语义或复制构造函数和复制赋值以及隐藏移动语义吗?

c++ destructor move c++11 rule-of-zero

16
推荐指数
2
解决办法
2463
查看次数

编写构造函数/析构函数是一种好习惯吗?

我想知道即使我不使用它们也总是编写构造函数/析构函数是一个好习惯.

class Foo
{
public:
    Foo(){};
    ~Foo(){};
};
Run Code Online (Sandbox Code Playgroud)

或者只有在我实际使用它们时才更好地编写它们?

class Foo
{
public:
};
Run Code Online (Sandbox Code Playgroud)

c++ constructor destructor class

7
推荐指数
1
解决办法
395
查看次数

即使定义了析构函数也进行移动操作

我读到了这个:

N3337 [class.copy]/9:如果类 X 的定义没有显式声明移动构造函数,则当且仅当

X 没有用户声明的复制构造函数,X 没有用户声明的复制赋值运算符,X 没有用户声明的移动赋值运算符,X 没有用户声明的析构函数,并且移动构造函数将不能隐式定义为已删除。声明析构函数并将其定义为默认值算作用户声明。

这里:默认的虚拟析构函数是否会阻止编译器生成的移动操作?

然而,这段代码:

struct A1 { virtual ~A1() {};  };

struct B1 : public A1 {
    ~B1() override {};  };

struct A2 { virtual ~A2() = default;  };

struct B2 : public A2 {
    ~B2() override = default;  };

struct A_NO_VIRTUAL {
    ~A_NO_VIRTUAL() {};  };

struct B_NO_VIRTUAL : public A_NO_VIRTUAL {
    ~B_NO_VIRTUAL() {};  };


int main() {  std::cout << std::is_nothrow_move_constructible_v<B1> << std::is_nothrow_move_constructible_v<B2> << std::is_nothrow_move_constructible_v<B_NO_VIRTUAL> << std::endl; }
Run Code Online (Sandbox Code Playgroud)

打印数量:111

请参阅:http …

c++

2
推荐指数
1
解决办法
75
查看次数

如果我声明解构函数但与默认解构函数完全相同,编译器是否仍会生成默认移动构造函数?

在这种情况下,我对默认函数生成的规则感到困惑:

对于最简单的类:

B 类{};

它将自动生成移动构造函数。

然而,如果为了

B 类{ public: ~B(){} }

我想它应该和默认的解构函数一样,这时候我会有一个默认的移动构造函数吗?我怎样才能检查它?

class A{
public:
    A() {}
    A(const A& lv) {cout << "a copy ctor." << endl;}
    A(A&& rv) {cout << "a move ctor." << endl;}
};

class B{
public:
    //~B(){}
private:
    A a;
};

int main()
{
    B b;
    B b2(std::move(b));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我尝试了这个方法,似乎答案是否定的,但我不确定。

c++ constructor class

2
推荐指数
1
解决办法
117
查看次数