我在接受采访时被问到这个问题,我无法回答这个问题.
更具体地说,赋值运算符所属的类如下所示:
class A {
private:
B* pb;
C* pc;
....
public:
....
}
Run Code Online (Sandbox Code Playgroud)
如何为此类实现原子(线程安全)和异常安全的深层复制赋值运算符?
这只是一个快速的问题,可以正确理解当您使用如下构造函数创建类时会发生什么:
class A
{
public:
A() {}
};
Run Code Online (Sandbox Code Playgroud)
我知道没有生成默认构造函数,因为它已经定义,但是由编译器生成的复制和赋值构造函数,或者换句话说,我是否需要声明私有复制构造函数和私有赋值运算符以防止这种情况发生?
class A
{
private:
// needed to prevent automatic generation?
A( const A& );
A& operator=( const A& );
public:
A() {}
};
Run Code Online (Sandbox Code Playgroud) c++ copy-constructor default-constructor assignment-operator
复制赋值运算符具有通常的签名:
my_class & operator = (my_class const & rhs);
Run Code Online (Sandbox Code Playgroud)
以下签名是否有实际用途?
my_class const & operator = (my_class const & rhs);
Run Code Online (Sandbox Code Playgroud)
您只能定义一个或另一个,但不能同时定义两者.
我在某些语言中知道以下内容:
a += b
Run Code Online (Sandbox Code Playgroud)
比以下更有效:
a = a + b
Run Code Online (Sandbox Code Playgroud)
因为它不需要创建临时变量.这是C的情况吗?使用+ =更高效(因此也是-= *=等)
我觉得这个问题很基本,可以在某个地方出现,但我似乎无法找到答案.
假设我有这个代码:
//class member function
std::map< std::string, std::string > myMap;
const std::map< std::string, std::string >& bar()
{
return myMap;
}
void myFunc( std::map< std::string, std::string >& foo1 )
{
foo1 = bar();
std::map< std::string, std::string >& foo2 = bar();
}
Run Code Online (Sandbox Code Playgroud)
我的理解是,如果我开始使用foo2,因为foo2是对bar()返回的同一实例的引用,我用foo2做的任何事都将反映在myMap中.但是foo1怎么样?foo1是否获得了myMap的副本,还是指向与bar()返回的实例相同的实例?c ++标准库说std :: map的赋值运算符会复制元素,但这是否意味着在foo2的声明中没有真正调用赋值运算符?
谢谢!
我正在尝试将复制和交换习惯用法放入可重用的混音中:
template<typename Derived>
struct copy_and_swap
{
Derived& operator=(Derived copy)
{
Derived* derived = static_cast<Derived*>(this);
derived->swap(copy);
return *derived;
}
};
Run Code Online (Sandbox Code Playgroud)
我打算通过CRTP混合:
struct Foo : copy_and_swap<Foo>
{
Foo()
{
std::cout << "default\n";
}
Foo(const Foo& other)
{
std::cout << "copy\n";
}
void swap(Foo& other)
{
std::cout << "swap\n";
}
};
Run Code Online (Sandbox Code Playgroud)
但是,一个简单的测试显示它不起作用:
Foo x;
Foo y;
x = y;
Run Code Online (Sandbox Code Playgroud)
这仅打印两次"默认",不打印"复制"或"交换".我在这里错过了什么?
根据我的理解,我可以通过定义私有拷贝构造函数和赋值运算符来"禁用"复制和分配给我的对象:
class MyClass
{
private:
MyClass(const MyClass& srcMyClass);
MyClass& operator=(const MyClass& srcMyClass);
}
Run Code Online (Sandbox Code Playgroud)
但这有什么用呢?
它被认为是一种不好的做法吗?
如果您能够描述这种情况,我将不胜感激,以这种方式"禁用"赋值和复制构造函数是合理/有用的.
如果T是具有赋值运算符的默认签名的类类型,那么我们可以编写:
T const &ref = ( T{} = something );
Run Code Online (Sandbox Code Playgroud)
这创造了一个悬垂的参考.但是,签名:
T &operator=(T t) &
Run Code Online (Sandbox Code Playgroud)
带有悬空引用的上述代码将无法编译.这可以防止我们返回指定临时对象的左值的一些情况 - 不良情况,因为它们可能导致悬空引用.
有没有理由不这样做; 我们是否会禁用赋值运算符的任何有效用例?
我认为相同的注释也可以应用于复合赋值运算符+=等.更现实的情况可能是:
std::string const &s = std::string("Hello, ") += "world!";
Run Code Online (Sandbox Code Playgroud)
在运行时UB之前,拼写错误会被忽视.
我需要禁用复制赋值运算符.这将有效:
A& operator=(const A&);
Run Code Online (Sandbox Code Playgroud)
如果我没有指定确切的参数,它会工作operator=吗?
我的意思是这样的:
void operator=(void);
Run Code Online (Sandbox Code Playgroud)
返回值是正确的,我可以写任何我想要的,但参数类型怎么样?
这会覆盖operator=类的默认值吗?
在 perl5 中,您可以将其\视为一个指针,并通过以特定的 sigil 或->. 您还拥有使符号显式的 typeglob。在 perl5 中,底层的 C 代码结构将提供一个与语言语法相关的良好模型。
在 Raku 中,您有一组概念,例如:容器(和非容器?)、绑定、使用=and赋值、:=参数中的不同特征raw和rw和和\(似乎与 perl5 无关\?)。
是否有一些基础模型可以用来确定我在代码中的某个点实际使用的内容以及我有哪些选项?