C++类复制(指针复制)

Cha*_*emp 10 c++ pointers class

我的理解是,当您复制定义指针变量的类时,指针会被复制,但指针指向的数据却不会复制.

我的问题是:是否假设在这种情况下"指针复制"只是实例化一个相同类型的新指针(动态内存分配)?例如,新指针只是一个包含任意内存地址的新分配,应该注意指向适当内存地址的新指针?

我认为对这个问题有一个非常简单的答案,我为它的微不足道的性质道歉,但我试图在更深层次上理解指针,这出现在我对互联网的研究指针上.

问候,

乍得

Mar*_*ett 18

指针将被简单地复制为一个值 - 因此两个类都将指向相同的原始内存,不会发生新的分配.浅拷贝 - 这是默认情况下语言的作用.

如果您需要分配新内存并复制数据,则必须在复制构造函数中自行完成.深层复制 - 你必须自己做

编辑:这是C++的优势之一,您可以自由决定复制的工作原理.可能是仅对存储器进行读访问的对象的副本可以避免复制存储器的成本.如果新对象需要执行写操作,您还可以实现仅生成原始数据副本的类.


Pau*_*aul 8

首先,类中的指针是静态的(即编译器知道此类中有一个指针,它的大小是多少,因此在实例化类时不需要动态内存分配).

如果复制类(并且没有定义特殊的复制构造函数),则新类中的指针将指向内存中与旧类中的指针相同的位置.澄清:

#include <iostream>

class A {
   public:
       int *p;
};

int main() {
    A a,b;
    a.p = new int(10);
    b = a;

    std::cout << "*(a.p) = " << *(a.p) << std::endl; // 10
    std::cout << "*(b.p) = " << *(b.p) << std::endl; // 10

    *(b.p) = 3;

    std::cout << "*(a.p) = " << *(a.p) << std::endl; // 3
    std::cout << "*(b.p) = " << *(b.p) << std::endl; // 3

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果要在复制时分配新内存,则需要编写复制构造函数和复制赋值构造函数:

#include <iostream>

class A {
   public:
       int *p;

       A() : p(0) {}
       A(const A& other) { // copy constructor
           p = new int(*other.p);
       }

       A& operator=(const A& other) { // copy assignment constructor
           // protect against self assignment
           if (this != &other) {
               if (p != 0) {
                   *p = *other.p;
               } else { // p is null - no memory allocated yet
                   p = new int(*other.p);
               }
           }
           return *this;
       }

       ~A() { // destructor
           delete p;
       }
};


int main() {
    A a,b;
    a.p = new int(10);
    b = a;

    std::cout << "*(a.p) = " << *(a.p) << std::endl; // 10
    std::cout << "*(b.p) = " << *(b.p) << std::endl; // 10

    *(b.p) = 3;

    std::cout << "*(a.p) = " << *(a.p) << std::endl; // 10
    std::cout << "*(b.p) = " << *(b.p) << std::endl; // 3

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

执行此操作时,还应编写析构函数(请参阅Rule of three),因为如果类被销毁,则需要在复制/复制赋值构造函数中分配的内存: