【问题标题】:Weird behavior with OOP and string pointersOOP 和字符串指针的奇怪行为
【发布时间】:2018-07-09 03:47:32
【问题描述】:

这是我的代码:

#include <iostream>
#include <string>

class Human
{
public:
    std::string * name = new std::string();
    void introduce();
};

void Human::introduce()
{
    std::cout << "Hello, my name is " << Human::name << std::endl;
}

int main()
{
    Human * martha;
    martha->name = new std::string("Martha");
    martha->introduce();

    return 0;
}

嗯,它应该打印出如下消息: “你好,我的名字是玛莎”,但它既不打印“你好,我的名字是”字符串,也不打印“玛莎”的名字。为什么会发生?

【问题讨论】:

  • martha-&gt;name 通过访问未初始化的变量 martha 表现出未定义的行为。您的程序永远不会创建Human 的实例。你为什么在任何地方都使用指针? C++ 不是 Java。
  • 请打开并且不要忽略您的编译器警告。它应该告诉您至少在定义之前使用了martha
  • 我在学习COCOS2D-X,模板里面的指针太多了,看不懂。归根结底,我想了解它们。
  • @jafactor 你应该错过了 Ken Y-N 评论中的“开启”部分。
  • @jafactor 我正在学习 COCOS2D-X,模板中有很多我看不懂的指针 -- SDK 和 API 适用于那些已经在 API/SDK 所针对的语言方面有经验。它不是用来学习 C++ 基础的。

标签: c++ oop pointers


【解决方案1】:

解决方法很简单,就是彻底删除所有指针;请参阅下面的代码。我可以详细解决您的代码的许多问题,包括内存泄漏、未初始化的变量和指针的一般滥用,但似乎您可能来自不同的语言背景,应该花时间学习好的做法以及来自good C++ book 的现代 C++ 中的重要语义和习语。

#include <iostream>
#include <string>

class Human
{
public:
    std::string name;
    void introduce();
};

void Human::introduce()
{
    std::cout << "Hello, my name is " << name << std::endl;
}

int main()
{
    Human martha;
    martha.name = "Martha";
    martha.introduce();

    return 0;
}

【讨论】:

    【解决方案2】:

    需要对代码进行少量修改。 下面包括更新的代码以及对所做更改的 cmets。

    #include <iostream>
    #include <string>
    
    class Human
    {
    public:
        //Removed pointer to a string
        //Cannot have an instantiation inside class declaration
        //std::string * name = new std::string();
        //Instead have a string member variable
        std::string name;
        void introduce();
    };
    
    void Human::introduce()
    {
        //Human::name not required this is a member function
        //of the same class
        std::cout << "Hello, my name is " << name << std::endl; 
    }
    
    int main()
    {
        Human *martha = new Human();
        //Assign a constant string to string member variable
        martha->name = "Martha";
        martha->introduce();
    
        return 0;
    }
    

    正如@alter igel 所建议的那样,The Definitive C++ Book Guide and List 将是一个不错的起点。

    【讨论】:

    • 漂亮的答案。为什么它是恒定的?为了写一个常量,我不需要写“const”关键字吗?
    • 常量字符串我的意思是你给了一个完整的名字,而不是给它分配一个变量。因为我们给出的是“Martha”而不是 martha->name = nameOfPerson,其中 nameOfPerson 是一个具有实际字符串的变量。
    【解决方案3】:
    #include <iostream>
    #include <string>
    
    class Human {
    public:
        void Human(std::string* n) { name = n; }
        void introduce();
    private:
        std::string* name;
    };
    
    void Human::introduce() {
        std::cout << "Hello, my name is " << name << std::endl;
    }
    
    int main() {
        Human* martha = new Human(new std:string("Martha"));
        martha->introduce();
    
        return 0;
    }
    

    试试看。不同之处在于,您不在类定义中初始化变量,而是使用构造函数初始化名称。您可以将方法定义拆分为自己的部分,但它只有一行,并且可以放在类定义中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-22
      • 2021-07-01
      相关资源
      最近更新 更多