C++中的自定义私有专用复制构造函数

yrdbyhpb  于 2023-04-01  发布在  其他
关注(0)|答案(2)|浏览(173)

已锁定13小时。此问题的评论已被禁用,但仍在接受新答案和其他交互。Learn more

我想为我的类创建一个特定函数所需的自定义复制构造函数,与主复制构造函数相比,它需要执行更少的复制。我想出了传递一个虚拟变量:

class MyClass {
public:
    MyClass(double _d) : d(_d) {}
    MyClass(const MyClass& other) : d(other.d) {
        // does computationally expensive stuff
    }
private:
    MyClass(const MyClass& other, int) :d(other.d) {
        // is optimized for specific use case
    }
    const double d;
};

我想问是否有一个标准的约定或记录的方法来做到这一点,或者这是否是一个好主意。我知道传递一个虚拟变量与重载前缀和后缀++操作符的过程相同:

T& operator++();
T operator++(T);

也许这也适用于我的情况...
如果你想知道为什么我不使用自由函数,我需要使用构造函数,因为我必须初始化需要初始化列表的变量。
如果你不理解这个问题,这里有一个类可以让一切变得清晰:

class Braindead {
public:
    Braindead(double _d) : d(_d) {
        needed = 1;
        not_needed = 2;
    }
    Braindead(const Braindead& other) : d(other.d) {
        needed = other.needed;
        not_needed = other.not_needed;
    }
    void set_not_needed(int v) { not_needed = v; }
    void set_needed(int v) { needed = v; }
private:
    Braindead(const Braindead& other, int) :d(other.d) {
        needed = other.needed;
        //not_needed ignored
    }
    const double d;
    int needed;
    int not_needed;
};

我只复制我的特定用例所需的东西,私下。

nhn9ugyo

nhn9ugyo1#

我知道你的代码只是一个例子,虽然我不明白为什么。注意MyClass(const MyClass& other, int)不是复制构造函数。copy constructorMyClass(const MyClass&)而不是其他东西。这个区别很重要,因为大多数时候复制构造函数是在你进行复制时隐式调用的:

void foo(Example);
 Example a;
 Example b = a; // calls the copy constructor
 foo(b);        // calls the copy constructor

MyClass(const MyClass& other, int)不是一个复制构造函数。如果你同意的话,那就好。它不是一个在复制时会被隐式调用的构造函数。
我知道传递一个伪变量与重载前缀和后缀++运算符的过程是一样的:
使用重载解析是一个好主意。虽然你不会得到与++相同的效果。++需要特殊的语言支持来区分operator++()operator++(int)。你的构造函数不能得到这种支持。
我不完全确定你是否想保持某些成员未初始化。你不应该这样做。而是重新考虑你的设计。如果MyClass在某些地方做的比你需要的多,那么这就是设计的味道。很可能MyClass对一个类做的太多了(参见单一责任原则)。
但是,如果你想要一个构造函数,它只对一个函数进行某种类型的复制,你可以这样做:

#include <iostream>

struct MyClass;

void foo(MyClass&);

struct Proxy {
    MyClass& object;
private:
    Proxy(MyClass& object) : object(object) {}
    friend void foo(MyClass&);
};

struct MyClass  {
    MyClass() = default;
    MyClass(const Proxy& p) {} // implement special copy here
    MyClass(const MyClass&) = default; // copy constructor
};

void foo(MyClass& a) {
    MyClass b = Proxy(a);
}

int main() {
    MyClass a;
    MyClass b = Proxy(a); // fails to compile
}

注意foo如何只访问MyClass(const Proxy& p),而不访问MyClass可能拥有的任何私有部分。

qjp7pelc

qjp7pelc2#

我认为一个可能的解决办法是:

class MyClass {
public:
    MyClass(double _d) : d(_d) /*...*/ {}
    MyClass(const MyClass& other) : d(other.d) /*...*/ {
        // does computationally expensive stuff
    }
private:
    class SpecificCopy {
    public:
        SpecificCopy(const MyClass&);
    private:
        // only the needed members
    };
    
    const double d;
    // other members
};

让我知道你的想法...

相关问题