【问题标题】:C++ syntax for interaction between classes and struct用于类和结构之间交互的 C++ 语法
【发布时间】:2016-02-24 07:57:04
【问题描述】:

我在 C++ 的第一学期正在做一个作业,但我无法弄清楚它的工作语法。我需要使用指针将结构作为参数传递给类函数。我复制的这段代码是我最好的尝试,它会编译,但当它要求输入名字时它会崩溃。当我尝试更改语法时,我收到有关不完整结构、未定义变量(warrior was 或无效运算符)的错误。我做错了什么?

#include <iostream>

using namespace std;

class StarWars
{
    public:
        int totalNumber;
        struct data_clone
        {
            int ID, timeCounter;
            string name;
        };
        data_clone *warrior;
        void createClone()
        {
            cout << "How many clone warriors do you want to create in total?" << endl;
            cin >> totalNumber;
        }
        void input(struct data_clone *pointer, int total)
        {

            for(int i = 1; i <= total; i++)
            {
                cout << "For warrior number " << i << ":" << endl;
                cout << "What is the warrior's name?" << endl;
                cin >> pointer[i].name;
                cout << "What is the warrior's ID number?" << endl;
                cin >> pointer[i].ID;
                cout << "What is the warrior's time counter?" << endl;
                cin >> pointer[i].timeCounter;
            }
        }
        void lifeSpan(struct data_clone *pointer, int total)
        {
            for(int i = 1; i <= total; i++)
            {
                cout << "Warrior number " << pointer[i].name << ": " << endl;
                while(pointer[i].timeCounter > 0)
                {
                    cout << "Warrior name: " << pointer[i].name << endl;
                    cout << "Warrior ID number: " << pointer[i].ID << endl;
                    cout << "Warrior time counter: " << pointer[i].timeCounter << endl;
                    cout << "Clone is alive." << endl;
                    pointer[i].timeCounter--;
                }
                cout << "Warrior name: " << pointer[i].name << endl;
                cout << "Warrior ID number: " << pointer[i].ID << endl;
                cout << "Warrior time counter: " << pointer[i].timeCounter << endl;
                cout << "Clone is dead." << endl;
            }
        }


};

int main(void)
{
    StarWars clones;
    clones.createClone();
    clones.input(clones.warrior, clones.totalNumber);
    clones.lifeSpan(clones.warrior, clones.totalNumber);
}

【问题讨论】:

  • 似乎warrior 是一个悬空指针。
  • structclass 在 C++ 中基本相同,因此没有特殊规则可以让一个与另一个“交互”。
  • 你有一个指针,但你从未将它设置为指向任何地方。

标签: c++ pointers struct


【解决方案1】:

您没有初始化内存战士指向的内存,因此您正在使用未初始化的内存 - 总是一件坏事。这里有两点要记住:

使用指针时,总是先初始化它们后面的内存。更喜欢使用 RAII 概念,例如 std::unique_ptr / std::shared_ptr

void DoStuff(Widget* w);

std::unique_ptr<Widget> pw = std::make_unique<Widget>();
DoStuff(w.get());

使用普通变量时,使用解引用/引用运算符获取指向变量的指针。

void DoStuff(Widget* w);

Widget widget;
DoStuff(&w);

【讨论】:

  • 感谢您提供的信息——我现在正在阅读这些智能指针。我不认为教授打算让我们将它们用于这项特定的任务,但我总是很高兴学习更好的做事方法!
【解决方案2】:
struct data_clone
{
    int ID, timeCounter;
    string name;
};

class StarWars
{
private:
       data_clone *warrior;
       int totalNumber;
    public:
        StarWars()
        {

        }
        ~StarWars()
        {
            delete[] warrior; // clean up 
        }

        void createClone();
        void input();
        void lifeSpan();
  };

void StarWars::createClone()
{
    cout << "How many clone warriors do you want to create in total?" << endl;
    cin >> totalNumber;
    // construct structure baased on input
    warrior = new data_clone[totalNumber];
}

 void StarWars::input()
{

    for(int i = 0; i < totalNumber; i++)
    {
        cout << "For warrior number " << i+1 << ":" << endl;
        cout << "What is the warrior's name?" << endl;
        cin >> warrior[i].name;
        cout << "What is the warrior's ID number?" << endl;
        cin >> warrior[i].ID;
        cout << "What is the warrior's time counter?" << endl;
        cin >> warrior[i].timeCounter;
    }
}

void StarWars::lifeSpan()
{
    std::cout<<"**********Print data**********\n";
    for(int i = 0; i < totalNumber; i++)
    {
        cout << "Warrior number " << warrior[i].name << ": " << endl;
        while(warrior[i].timeCounter > 0)
        {
            cout << "Warrior name: " << warrior[i].name << endl;
            cout << "Warrior ID number: " << warrior[i].ID << endl;
            cout << "Warrior time counter: " << warrior[i].timeCounter << endl;
            cout << "Clone is alive." << endl;
            warrior[i].timeCounter--;
        }
        cout << "Warrior name: " << warrior[i].name << endl;
        cout << "Warrior ID number: " << warrior[i].ID << endl;
        cout << "Warrior time counter: " << warrior[i].timeCounter << endl;
        cout << "Clone is dead." << endl;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    StarWars clones;
    clones.createClone();
    clones.input();
    clones.lifeSpan();

    return 0;
}

【讨论】:

    【解决方案3】:

    你从来没有创建过你的克隆,你只知道应该有多少。
    为他们分配空间:

    void createClone()
    {
        cout << "How many clone warriors do you want to create in total?" << endl;
        cin >> totalNumber;
        warrior = new data_clone[totalNumber];
    }
    

    您的数组索引也关闭了 - 大小为 N 的数组的索引从 0N - 1

    但更常见的处理方式是将数量传递给构造函数,让对象处理自己的成员:

    class StarWars
    {
    public:
        StarWars(int clones)
            : totalNumber(clones),
              warrior(new data_clone[clones])
        {
    
        }
    
        void input()
        {
            for(int i = 0; i < totalNumber; i++)
            {
                cout << "For warrior number " << i << ":" << endl;
                cout << "What is the warrior's name?" << endl;
                cin >> warrior[i].name;
                cout << "What is the warrior's ID number?" << endl;
                cin >> warrior[i].ID;
                cout << "What is the warrior's time counter?" << endl;
                cin >> warrior[i].timeCounter;
            }
        }
    
        void lifeSpan()
        {
            for(int i = 0; i < totalNumber; i++)
            {
                cout << "Warrior number " << i << ": " << endl;
                while(warrior[i].timeCounter > 0)
                {
                    cout << "Warrior name: " << warrior[i].name << endl;
                    cout << "Warrior ID number: " << warrior[i].ID << endl;
                    cout << "Warrior time counter: " << warrior[i].timeCounter << endl;
                    cout << "Clone is alive." << endl;
                    warrior[i].timeCounter--;
                }
                cout << "Warrior name: " << warrior[i].name << endl;
                cout << "Warrior ID number: " << warrior[i].ID << endl;
                cout << "Warrior time counter: " << warrior[i].timeCounter << endl;
                cout << "Clone is dead." << endl;
            }
        }
    
    private:
        int totalNumber;
        struct data_clone
        {
            int ID, timeCounter;
            string name;
        };
        data_clone *warrior;
    };
    
    int main()
    {
        int number = 0;
        cout << "How many clone warriors do you want to create in total?" << endl;
        cin >> number;
        StarWars clones(number);
        clones.input();
        clones.lifeSpan();
    }
    

    请注意,您还需要正确处理析构函数、复制构造函数和赋值运算符(留作练习)。

    【讨论】:

    • 非常感谢,您的最佳解决方案解决了当前的问题(教授似乎打算让我这样做)。正如你提到的,我现在正在尝试使用构造函数等。
    【解决方案4】:

    类星球大战 { 私人的: 结构数据克隆 { 整数 ID,时间计数器; 字符串名称; };

    public:
        StarWars()
        {
            warrior = new data_clone[4];
        }
        ~StarWars()
        {
            delete[] warrior;
        }
        int totalNumber;
    
        data_clone *warrior;
        void createClone()
        {
            cout << "How many clone warriors do you want to create in total?" << endl;
            cin >> totalNumber;
        }
        void input(struct data_clone *pointer, int total)
        {
    
            for(int i = 0; i < total; i++)
            {
                cout << "For warrior number " << i << ":" << endl;
                cout << "What is the warrior's name?" << endl;
                cin >> pointer[i].name;
                cout << "What is the warrior's ID number?" << endl;
                cin >> pointer[i].ID;
                cout << "What is the warrior's time counter?" << endl;
                cin >> pointer[i].timeCounter;
            }
        }
        void lifeSpan(struct data_clone *pointer, int total)
        {
            for(int i = 0; i < total; i++)
            {
                cout << "Warrior number " << pointer[i].name << ": " << endl;
                while(pointer[i].timeCounter > 0)
                {
                    cout << "Warrior name: " << pointer[i].name << endl;
                    cout << "Warrior ID number: " << pointer[i].ID << endl;
                    cout << "Warrior time counter: " << pointer[i].timeCounter << endl;
                    cout << "Clone is alive." << endl;
                    pointer[i].timeCounter--;
                }
                cout << "Warrior name: " << pointer[i].name << endl;
                cout << "Warrior ID number: " << pointer[i].ID << endl;
                cout << "Warrior time counter: " << pointer[i].timeCounter << endl;
                cout << "Clone is dead." << endl;
            }
        }
    

    };

    注意:我只是硬编码,这不是正确的方法,它迫使你只输入 4 种类型的数据克隆 "战士 = 新数据克隆[4];"

    你至少会得到你的结果

    【讨论】:

    • 考虑到这是 OP 对 C++ 的第一次分配,他们很可能不熟悉 new/delete 以及 C++ 中分配内存的优点/缺点,你的答案应该更好地详细说明这一点,而不是给他们更多要复制的内容。
    猜你喜欢
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多