为什么未调用副本分配方法?

时间:2019-06-09 10:11:39

标签: c++

我想知道为什么未调用复制分配运算符,但似乎仍在执行分配吗?这是我的代码:

@echo off
echo \        / |     |   /\     ___ |  /
echo  \      /  |     |  /  \  /     | /
echo   \    /   |-----| /    \ |     |/
echo    \  /    |     | |----| |     |\
echo     \/     |     | |    |  \___ | \
echo Welcome to VHACK!(continued with more echo's and code)
pause
exit

未打印分配运算符中的 cout

更新我的代码-根据先前的建议。这按预期工作

#include <cstring>
#include <iostream>

   class String{
       public:
            String(){ std::cout << "Empty Ctor" << '\n'; }
            String(const char* s):data{(char*)s}{ std::cout << "Args Ctor"; }
            Strin& operator=(const String&);
            char* showData(){ return *data; }
       private:
             char* data;
    };

    String& String::operator=(const String& s){
        std::cout << "Copy Assignment" << '\n'; // <- This is NEVER printed
        delete [] data;
        data = new char[strlen(s.data)+1];
        strcpy(data, s.data);
        return *this;
    }

    int main(){
        String* s1 = new String("Hello");
        String* s2 = new String("World");

        s2 = s1;   // This should call the overloaded copy assignment operator!?

        std::cout << s2->showData() << '\n'; // prints "Hello"

        return 0;
    }

4 个答案:

答案 0 :(得分:3)

s2 = s1;只是指针之间的赋值,它不会调用复制赋值运算符,只会使s2指向由s1指向的同一对象。

您可能想尝试使用*s2 = *s1;的副本分配运算符的String。但是您实际上并不需要原始指针,只需

String s1("Hello");
String s2("World");

s2 = s1;   // This would call the overloaded copy assignment operator

std::cout << s2.showData() << '\n'; // prints "Hello"

答案 1 :(得分:3)

“ s2 = s1; //应该调用重载的副本分配运算符!?”

不。它不应该。

您只是将一个指针变量的值分配给另一个。指针指向的对象没有复制分配。

这将如您所愿:

String s1("Hello");
String s2("World");
s1 = s2;

*s1 = *s2;

使用原始代码。

答案 2 :(得分:2)

好吧,让我们以此开始吧,指针不是字符串,而是指针(指向字符串)。

所以这个:

String* s1 = new String ("BLE");

在内存中的某个位置创建一个字符串,该字符串将指向该字符串。因此,它的表示形式是:

     +--------+
s -> | 0x005  |----+
     +--------+     \
                     \
                      \
                       \
                        \
      +---+---+---+---+---+---+---+
      |   |   |   |   | B | L | E |
      +---+---+---+---+---+---+---+
     0x 1   2   3   4   5   6   7

此:

  String* s2;
  s2 = s1;

使s2指向相同的地址(在指针的分配位置保持相同的值):

     +--------+
s1-> | 0x005  |+
     +--------+ \
                 \
     +--------+   \
s2-> | 0x005  |----+
     +--------+     \
                     \
                      \
      +---+---+---+---+---+---+---+
      |   |   |   |   | B | L | E |
      +---+---+---+---+---+---+---+
     0x 1   2   3   4   5   6   7

=中的运算符String适用于字符串类型,而不适用于指针,因此,如果您有类似这样的内容:

String s1 = "BLA";
String s2 = s1;

这将创建一个全新的对象并将数据复制到该新对象上。

我建议您阅读使用C ++编程原理和实践第18.5章。

我也相信您的代码中有很多错误。你不能做你正在做的事。

以下是您的代码示例,该示例实际上使用了副本分配:

#include <cstring>
#include <iostream>

class String{
   public:
        String() : data {new char[1]} { std::cout << "Empty Ctor\n" << '\n'; }
        String(const char* s):data{new char[strlen(s)]}{ strcpy (data, s); std::cout << "Args Ctor\n"; }
        String& operator=(const String&);
        char* showData(){ return data; }
   private:
         char* data;
};

String& String::operator=(const String& s){
    std::cout << "Copy Assignment" << '\n'; // <- This is NEVER printed
    delete[] data;
    data = new char[strlen(s.data)+1];
    strcpy(data, s.data);
    return *this;
}

int main(){
    String s1 ("Hello");
    String s2 ("World");

    s2 = s1;   // This should call the overloaded copy assignment operator!?

    std::cout << s2.showData() << '\n'; // prints "Hello"

    return 0;
}

或其他建议:

#include <cstring>
#include <iostream>

class String{
   public:
        String() : data {new char[1]} { std::cout << "Empty Ctor\n" << '\n'; }
        String(const char* s):data{new char[strlen(s)]}{ strcpy (data, s); std::cout << "Args Ctor\n"; }
        String& operator=(const String&);
        char* showData(){ return data; }
   private:
         char* data;
};

String& String::operator=(const String& s){
    std::cout << "Copy Assignment" << '\n'; // <- This is NEVER printed
    delete[] data;
    data = new char[strlen(s.data)+1];
    strcpy(data, s.data);
    return *this;
}

int main(){
    String* s1 = new String("Hello");
    String* s2 = new String("World");

    *s2 = *s1;   // This should call the overloaded copy assignment operator!?

    std::cout << s2->showData() << '\n'; // prints "Hello"

    return 0;
}    

这就是为什么在开始弄乱C ++中的指针之前应该学习C和指针的原因。

答案 3 :(得分:1)

因为您正在将一个指针分配给另一个指针。这样做:

*s2 = *s1;