【问题标题】:How can I create multiple items with one class in C++?如何在 C++ 中使用一个类创建多个项目?
【发布时间】:2012-03-19 10:54:59
【问题描述】:

我的家具类有:

家具.h:

#include <iostream>
#include <string>
using namespace std;

class Furniture {
public:
    Furniture();
    ~Furniture();
    void setname(string name);
    void setprice(double price);
    double getprice();
    string getname();
    virtual void printSpecs();
private:
    string name;
    double price;
protected:
    static int NumberOfItems;
    int Id;

};

家具.cpp:

#include "furniture.h"

Furniture::Furniture() {
}
Furniture::~Furniture() {
}
void Furniture::setname(string name) {
    this->name = name;
}
string Furniture::getname()
{
    return this->name;
}
void Furniture::setprice(double price) {
    this->price = price;
}
double Furniture::getprice() {
    return this->price;
}
void Furniture::printSpecs() {
    cout<<"Price: "<<this->price<<endl;
    cout<<"Name: "<<this->name<<endl;
}

int main() {
    Furniture *model = new Furniture();
    model->setname("FinalDestiny");
    model->setprice(149.99);
    model->printSpecs();
    delete model;
}

一切正常,但我想添加多个具有相同类别的家具项目,只需更新 NumberOfItems。有什么办法吗?

另外,我的代码可以吗?我的意思是,我该如何改进它?我是 OOP 的新手,我想学习一些好的做法。

谢谢。

【问题讨论】:

    标签: c++ oop class methods


    【解决方案1】:

    这个想法在概念上被打破了。你不能这样做;你真的需要不同的对象。

    或者,如果您真的想要拥有多个相同的项目,您可以创建一个项目并创建多个指向它的指针,并为活动项目的数量维护一个单独的计数。例如,shared_ptr 就是这样做的。

    也就是说,你的代码根本不应该使用指针,这是 C++ 代码中常见的反模式。此外,您的代码可能不应该有 setter,而是提供适当的构造函数:

    int main() {
        Furniture model("FinalDestiny", 149.99);
        model.printSpecs();
    }
    

    更短、更简单,而且没有内存泄漏的可能性。

    【讨论】:

    • @FinalDestiny 不是。 C++ 专家一致认为 getter/setter 在大多数代码中被过度使用。它们在某些代码中确实有其用途(例如,没有它们就很难实现 DAO),但大多数代码不需要它们。它们不适合面向对象的代码,因为每个类都有一个特定的目的。
    • 尤其是getters。没有吸气剂是好的。告诉对象做你想做的事。与其他对象合作完成工作。例如。 printSpecs 可以使用 std::ostream 对象。这使得测试更容易,因为目前,您隐式耦合到 cout 对象。
    • 我正要说,setter 尤其表明了维护对象状态的责任在于 对象之外,它或多或少与 OO 原则相矛盾。在我和@PeterWood 之间,我们现在可以得出结论, getter 和 setter 都比另一个差。我相信这是一种禅意。
    【解决方案2】:

    要跟踪项目数,可以在构造函数中更新项目数:

    Furniture::Furniture() {
       Id = NumberOfItems++;
    }
    

    如果需要,可以在析构函数中递减:

    Furniture::~Furniture() {
       NumberOfItems--;
    }
    

    要通过Id 访问该项目,您需要有一个额外的管理器类或使用地图:

    std::map<int,Furniture*> items;
    

    您可以将其作为参数传递给构造函数并在那里更新:

    Furniture::Furniture(std::map& items) {
       Id = NumberOfItems++;
       items[Id] = this;
    }
    

    而且,在外面,您可以简单地检索项目:

    Furniture* f = items[3];
    

    【讨论】:

    • 是的,但是如何显示项目 1、2、3 的价格/名称?如何设置这些详细信息?
    • 你没有。如果您的班级代表一件家具,那么您不能将其中的许多家具放入其中。您应该有一个包含std::vector&lt;Furniture&gt; 或类似内容的类来存储多件家具。
    【解决方案3】:

    我会这样写

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Furniture {
    public:
        Furniture(string name = "", double price = 0)
            : name(name), price(price), Id(NumberOfItems++)
        {}
        Furniture(const Furniture &f)
            : name(f.getname()), price(f.getprice()), Id(NumberOfItems++)
        {}
    
        void setname(string name) { this->name = name; }
        void setprice(double price) { this->price = price; }
        double getprice() const { return price; }
        string getname() const { return name; }
    
        virtual void printSpecs() {}
    
    private:
        string name;
        double price;
    
    protected:
        static int NumberOfItems;
        int Id;
    };
    int Furniture::NumberOfItems;
    
    int main_furniture(int, char **)
    {
        Furniture a("product 1", 100);
        Furniture x(a), y(a), z(a);
    }
    

    我内联只是为了简化。你感兴趣的应该是 copy constructor 实现,并且(OT)你忘记了 getter 上的 const...

    【讨论】:

      【解决方案4】:

      只需在构造函数中增加NumberOfItems,并在析构函数中减少它。

      【讨论】:

      • 是的,但是如何访问项目 1、2、3 等?
      • 您希望保留一个静态的项目列表,以及一个计数器。在构造函数中将每个项目添加到列表中,并在析构函数中将其删除。
      • @FinalDestiny 类家具,不能同时作为一件家具和一个家具容器。您在单个实体中混合了两个不同的概念,为家具定义单独的容器。
      【解决方案5】:

      将家具实例存储在数组中,或者更好地存储在vector 中。您可以使用索引或迭代器访问它们。 NumberOfItems 字段不属于家具类,家具实例不应该知道系统中有多少家具物品。使用vector 中的size () 方法获取家具项目数。

      【讨论】:

        猜你喜欢
        • 2016-03-30
        • 2021-01-08
        • 1970-01-01
        • 2013-06-29
        • 2016-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-03
        相关资源
        最近更新 更多