C++中的复制构造函数

whitzsjs  于 2023-04-13  发布在  其他
关注(0)|答案(2)|浏览(181)

我的类有一个const方法,它需要执行一个示例的副本,以保持原始的一个常量(这可能被认为是糟糕的设计,但这是另一个讨论)。
如果只复制函数所需的成员变量而不是所有的变量,这将是有益的。我想这样做,但我也想在我复制的示例上使用方法。
这就是为什么我提出了一个私有的复制构造函数,它只复制我在函数中使用的方法所需要的东西。
注意:我被迫使用构造函数,因为我的类有只能由初始化器列表初始化的成员,即常量变量,引用,基类构造函数等。
我提出了这个构造函数,它与复制构造函数非常相似,但它接受一个虚拟变量作为输入,这样编译器就知道要调用哪个:

#include <ctime>

class MyClass {
public:
    MyClass(const MyClass& other);
    clock_t pure_func() const;
    void messy_method();
private:
    struct ForPureFunc {};
    MyClass(const MyClass& other, ForPureFunc);
};

下面是一个可能的方法的实现,它意味着没有副作用(请记住,这只是一个例子):

clock_t MyClass::pure_func() const {
    /* 
       lets say I want to time
       the messy method 
    */
    MyClass copy(*this, ForPureFunc());
    clock_t start = clock();
    for (int i = 0; i < 10000; ++i)
        copy.messy_method();
    return clock() - start;
}

我想问是否有人遇到过这样的事情,如果传递一个虚拟变量是一个使用的技术和一个好的。

5vf7fwbs

5vf7fwbs1#

我知道你的代码只是一个例子,虽然我不明白为什么。注意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可能拥有的任何私有部分。

8qgya5xd

8qgya5xd2#

我想到的一个可能的解决方案是这样的:

class MyClass {
public:
    MyClass(const MyClass& other);
private:
    class SpecificCopy {
    public:
        SpecificCopy(const MyClass&);
        // only the needed members
    };
    // other members
};

相关问题