首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何打印成员变量?

如何打印成员变量?
EN

Stack Overflow用户
提问于 2021-05-21 09:41:13
回答 2查看 84关注 0票数 0
代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Item {
protected:
    string modelName;
    int price;
    string itemId; // “modelName-seqNumber”
    static int seqNumber; // initialValue = 1
public:
    virtual void print() const = 0;

    void setname(const string& _name)
    {
        modelName = _name;
    }
    string& getitemId()
    {
        return itemId;
    }
};

class Monitor : public Item {
    const int size;
public:
    int seqNumber = 1;
    Monitor(const string& _name, const int _price, const int _size)
        : size(_size)
    {
        setname(_name);
        price = _price;
        itemId = modelName;
        itemId += '-';
        itemId += seqNumber;
    }
    void print() const {
        cout << modelName << ', ' << itemId << ', ' << price << ',' << size << endl;
    }
};

class CPU : public Item {
    const int speed;
public:
    int seqNumber = 1;
    CPU(const string& _name, const int _price, const int _speed)
        :speed(_speed)
    {
        setname(_name);
        price = _price;
    }
    
    void print() const {
        cout << modelName << ', ' << itemId << ', ' << price << ',' << speed << endl;
    }
};

class ItemList {
    vector<Item*> items;
    void copyItem(const ItemList& list) {
        for (const auto item : list.getItem())
            addItem(item);
    }
public:
    ItemList() = default;
    ItemList(const ItemList& list) {
        copyItem(list);
    }
    ItemList(ItemList& il)
    {
        for (const auto item : il.items)
            items.push_back(item);
    }
    vector<Item*> getItem() const { return items; }

    void addItem(Item* const _item) {
        items.push_back(_item);
    }
    void print() const {
        for (const auto item : items)
            item->print();
    }
    void removeItem(const string& _name)
    {
        for (vector<Item*>::iterator it = items.begin(); it != items.end(); it++)
            if ((*it)->getitemId() == _name)
                it = items.erase(it);
    }
};

上面是类。

下面是主要功能。

代码语言:javascript
复制
int main() {
    ItemList list1;
    {
        CPU cpu1("Intel", 200, 5); // modelName, price, speed
        CPU cpu2("Intel", 300, 7);
        list1.addItem(&cpu1); list1.addItem(&cpu2);
        Monitor monitor1("Samsung", 1000, 40); //modelName, price, size
        list1.addItem(&monitor1);
    }
    cout << "Section 1" << endl;
    list1.print();
    {
        ItemList list2(list1);
        cout << "Section 2" << endl;
        list2.print();
        list2.removeItem("Intel-2");
        cout << "Section 3" << endl;
        list2.print();
    }
    {
        ItemList list3;
        list3 = list1;
    }
    cout << "Section 4" << endl;
    list1.print();
}

嗨,我正在学习c++,我有一个问题!

我想打印modelName,但是当我运行这段代码时,打印了一些奇怪的数字。

而且“,”也没有打印出来。

我试着调试我的代码,但是失败了。

原因何在?我需要你的帮助!

感谢您的关注!

EN

回答 2

Stack Overflow用户

发布于 2021-05-21 09:58:04

代码语言:javascript
复制
{
    CPU cpu1("Intel", 200, 5); // modelName, price, speed
    CPU cpu2("Intel", 300, 7);
    list1.addItem(&cpu1); list1.addItem(&cpu2);
    Monitor monitor1("Samsung", 1000, 40); //modelName, price, size
    list1.addItem(&monitor1);
}

这在内部作用域中声明了两个对象,cpu1cpu2,将指向它们的指针传递给addItem,后者将它们保存在其内部向量中。monitor1也是如此。

在此作用域结束后,cpu1cpu2monitor1将超出作用域并被销毁。它们在向量中的指针现在指向被销毁的对象,以后使用这些指针会导致未定义的行为,其结果是您看到的垃圾输出。

票数 1
EN

Stack Overflow用户

发布于 2021-05-21 10:22:09

您的代码有几个bug,我将逐一指出它们。

将指针推送到在第一个范围之后不再存在的局部变量

代码语言:javascript
复制
    {
        CPU cpu1("Intel", 200, 5); // modelName, price, speed
        CPU cpu2("Intel", 300, 7);
        list1.addItem(&cpu1); list1.addItem(&cpu2);
        Monitor monitor1("Samsung", 1000, 40); //modelName, price, size
        list1.addItem(&monitor1);
    }

尝试打印具有char类型的字符串:

代码语言:javascript
复制
cout << modelName << ', ' << itemId << ', ' << price << ',' << size << endl;

将数字添加到字符串中,这将不起作用:

代码语言:javascript
复制
itemId += seqNumber;

我已经通过以下方式修复了你的代码:

  1. 将本地对象替换为指针:

代码语言:javascript
复制
    CPU* cpu1 = new CPU("Intel", 200, 5);  // modelName, price, speed
    CPU* cpu2 = new CPU("Intel", 300, 7);
    list1.addItem(cpu1);
    list1.addItem(cpu2);
    Monitor* monitor1 =
        new Monitor("Samsung", 1000, 40);  // modelName, price, size
    list1.addItem(monitor1);

  1. 向基类

添加虚拟析构函数

代码语言:javascript
复制
  virtual ~Item() = default;

  1. 为所有类添加克隆函数,以避免引用释放的对象:

代码语言:javascript
复制
class Monitor : public Item {
  const int size;

 public:
  int seqNumber = 1;
  Monitor(const string& _name, const int _price, const int _size)
      : size(_size) {
    setname(_name);
    price = _price;
    itemId = modelName;
    itemId += '-';
    itemId += std::to_string(seqNumber);
  }
  virtual Item* clone() override {
    return new Monitor(this->modelName, this->price, this->size);
  }
  void print() const {
    cout << modelName << ", " << itemId << ", " << price << ',' << size << endl;
  }
};

使用std::to_string将数字附加到字符串

代码语言:javascript
复制
itemId += std::to_string(seqNumber);

  1. 为对象添加深层副本:

代码语言:javascript
复制
  void copyItem(const ItemList& list) {
    for (const auto item : list.getItem()) addItem(item->clone());
  }
  ItemList(ItemList& il) {
    for (const auto item : il.items) items.push_back(item->clone());
  }

添加operator=

代码语言:javascript
复制
  ItemList& operator=(const ItemList& list) {
    for (auto* p : items) {
      delete p;
    }
    items.clear();
    copyItem(list);
    return *this;
  }

在析构函数中释放

  1. 调用以避免内存泄漏

代码语言:javascript
复制
  ~ItemList() {
    for (auto* p : items) {
      delete p;
    }
  }

remove item函数错误地处理了迭代器

代码语言:javascript
复制
  void removeItem(const string& _name) {
    for (vector<Item*>::iterator it = items.begin(); it != items.end();)
      if ((*it)->getitemId() == _name) {
        auto pre = *it;
        it = items.erase(it);
        delete pre;
      } else {
          ++it;
      }
  }

最后代码工作顺利,通常指针应该是std::unique_ptrstd::shared_pointer在这里是现代的c++,如果你喜欢它,我会更新答案。Online demo

shared_ptr版本已经完成,更容易维护,现在不需要手动管理内存,我强烈推荐它:

代码语言:javascript
复制
#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace std;

class Item {
 protected:
  string modelName;
  int price;
  string itemId;         // “modelName-seqNumber”
  static int seqNumber;  // initialValue = 1
 public:
  virtual void print() const = 0;
  virtual ~Item() = default;

  void setname(const string& _name) { modelName = _name; }
  string& getitemId() { return itemId; }
};

class Monitor : public Item {
  const int size;

 public:
  int seqNumber = 1;
  Monitor(const string& _name, const int _price, const int _size)
      : size(_size) {
    setname(_name);
    price = _price;
    itemId = modelName;
    itemId += '-';
    itemId += std::to_string(seqNumber);
  }
  void print() const {
    cout << modelName << ", " << itemId << ", " << price << ',' << size << endl;
  }
};

class CPU : public Item {
  const int speed;

 public:
  int seqNumber = 1;
  CPU(const string& _name, const int _price, const int _speed) : speed(_speed) {
    setname(_name);
    price = _price;
  }

  void print() const {
    cout << modelName << ", " << itemId << ", " << price << "," << speed
         << endl;
  }
};

class ItemList {
  vector<std::shared_ptr<Item>> items;
  void copyItem(const ItemList& list) {
    for (const auto item : list.getItem()) addItem(item);
  }

 public:
  ItemList() = default;
  ItemList(const ItemList& list) { copyItem(list); }
  ItemList(ItemList& il) {
    for (const auto item : il.items) items.push_back(item);
  }
  ItemList& operator=(const ItemList& list) {
    items.clear();
    copyItem(list);
    return *this;
  }
  ~ItemList() = default;
  vector<std::shared_ptr<Item>>& getItem() const { return items; }

  void addItem(std::shared_ptr<Item> _item) { items.push_back(_item); }
  void print() const {
    for (const auto item : items) item->print();
  }
  void removeItem(const string& _name) {
    for (auto it = items.begin(); it != items.end();)
      if ((*it)->getitemId() == _name) {
        it = items.erase(it);
      } else {
        ++it;
      }
  }
};

int main() {
  ItemList list1;
  {
    auto cpu1 =
        std::make_shared<CPU>("Intel", 200, 5);  // modelName, price, speed
    auto cpu2 = std::make_shared<CPU>("Intel", 300, 7);
    list1.addItem(cpu1);
    list1.addItem(cpu2);
    auto monitor1 = std::make_shared<Monitor>("Samsung", 1000,
                                              40);  // modelName, price, size
    list1.addItem(monitor1);
  }
  cout << "Section 1" << endl;
  list1.print();
  {
    ItemList list2(list1);
    cout << "Section 2" << endl;
    list2.print();
    list2.removeItem("Intel-2");
    cout << "Section 3" << endl;
    list2.print();
  }
  {
    ItemList list3;
    list3 = list1;
  }
  cout << "Section 4" << endl;
  list1.print();
}

Online demo

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67629847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档