C 使用std:String v char*在基类中 - 基类具有字符串的固定副本

c++ using std:string v char* in a base class - base class has a redudant copy of the string

本文关键字:基类 字符串 副本 String std char 使用      更新时间:2023-10-16

在下面的课程中,本教程中说

您也可以使m_speak成为std :: string,但是这样做的缺点 是每只动物都包含"说话"的冗余副本

我试图理解这一点,如何使用string而不是char*仅创建string而不是char*的冗余副本。

#include <string>
#include <iostream>
class Animal
{
protected:
    std::string m_name;
    const char* m_speak;
    // We're making this constructor protected because
    // we don't want people creating Animal objects directly,
    // but we still want derived classes to be able to use it.
    Animal(std::string name, const char* speak)
        : m_name(name), m_speak(speak)
    {
    }
public:
    std::string getName() { return m_name; }
    const char* speak() { return m_speak; }
};
class Cat: public Animal
{
public:
    Cat(std::string name)
        : Animal(name, "Meow")
    {
    }
};
class Dog: public Animal
{
public:
    Dog(std::string name)
        : Animal(name, "Woof")
    {
    }
};

与构造函数:

Cat(std::string name) : Animal(name, "Meow")

" Meow"是一个常数,将在内存中有一个地址。编译器将对每个Cat使用相同的常数。所有Cat对象的m_speak变量将指向该位置。

如果您将m_speak作为std::string,则变量m_speak将将" Meow"复制到其内部缓冲区中。每当您创建猫时,这都会发生,因此会有很多副本。

同样的事情适用于Dog和" Woof"。

const char*是指针。指针存储对象的内存地址(在这种情况下,字符串的第一个字符(。在这种情况下,每个实例的成员都指向同一字符串,因此字符串的内容没有重复。

std::string不是指针。每个 std::string对象都有自己的存储内容的缓冲区,因此每个实例都有成员存储的字符串的内容。