1

在创建类时,我被告知没有公共数据成员。很好,我明白为什么,但这是我的问题。我有一个在类中使用的结构(线性链表)。我真的很想将其中一个结构字段(一个数组)初始化为 NULL,以便我可以检查客户端是否传递给我有效的结构,而不是未初始化的充满垃圾值的结构。我意识到 C++ 不允许我在 struct 声明中设置默认值,那么如何防止客户端给我垃圾?

struct task {
    char *description;
    char *name;
    float time_remaining;
    float time_spent;
};

然后在我的课堂上,我正在尝试做类似的事情:

//I am making a copy of "to_add" and storing it in the LLL
int list::add_to_list(const task & to_add)
{ /.../ }

我不希望用户将一堆未初始化的“任务”添加到链接列表中......该怎么办?当我将该结构转换为一个类并将数据成员移动到私有时,我在尝试访问数据成员以复制它们时遇到了很多问题。我非常小心地不做任何事情来影响 var 的值,但我无法摆脱编译器给我关于“错误:将 'const task' 作为 'char* task::get_comp_name 的 'this' 参数传递”的错误()' 丢弃限定符 [-fpermissive]" ("get_comp_name") 是我确定没有编辑任何值的 getter 之一,只是传递给我一份副本)在我开枪之前请帮助我。在脸上。

4

3 回答 3

4

在 C++ 中 astruct和 aclass除了访问控制之外是相同的。所以结构对成员和继承的默认访问是公共的,而类是私有的。所以你可以给你的结构一个默认的构造函数和其他人来初始化它。

struct task {
    task() : desctiption(0), name(0), time_remaining(0.), time_spent(0.) {}
    char *description;
    char *name;
    float time_remaining;
    float time_spent;
};

添加构造函数的一个副作用是结构不再是聚合。这对您来说可能是也可能不是问题。

在 C++11 中,您还可以在声明时初始化成员:

struct task {
    char *description{nullptr};
    char *name{nullptr};
    float time_remaining{0};
    float time_spent{0};
};

这种就地初始化type x = y也接受语法,无参数{}初始化导致值初始化,这导致原始类型的初始化为零,因此示例中的参数可以省略。

于 2012-04-20T05:38:38.240 回答
2

这里有几个问题。

公开还是不公开?

公共属性看起来很方便,但它们通常会在您最不期望的时候回来咬您。我已经怀疑time_remainingand有问题time_spent:我想两者都是同时修改的,不是吗?

默认情况下,变量属性应该是private,以便类可以强制执行不变量,例如time_remaining + time_spent在任务的整个生命周期中都是常量

常量属性很好public,它们在不变量中的作用无论如何都在构造函数中一劳永逸地解决。

但是奇怪的错误信息?

这是因为您缺少好的教程或书籍。手头的问题很简单:这是一个const与 -ness 相关的问题。

const对象只能通过 const 引用或值传递给函数/方法,并且只能在const其上调用方法。在您的情况下,方法的正确声明name()应该在方法名称之后有一个const限定符。

总而言之

并投入,std::string因为它更容易操纵。

class Task {
public:
    Task(): time_remaining(0), time_spent(0) {}
    Task(std::string name, std::string desc, float duration):
        _name(name), _desc(desc), _time_remaining(duration), _time_spent(0) {}

    // Accessors
    std::string const& name() const { return _name; }
    std::string const& description() const { return _desc; }
    float time_remaining() const { return _time_remaining; }
    float time_spent() const { return _time_spent; }

    // Modifiers
    void spend(float duration) {
        _time_remaining -= duration;
        _time_spent += duration;
    }

private:
    std::string _name, _desc;
    float _time_remaining, _time_spent;
}; // class Task

Note: it could probably be beneficial to check that the duration passed to the spend method is not superior to the _time_remaining attribute, otherwise you spend more than you have...

于 2012-04-20T07:51:56.667 回答
1

为结构实现构造函数:

struct task {
    task() : description(0), name(0), time_remaining(0), time_spent(0) {}
    char *description;
    char *name;
    float time_remaining;
    float time_spent;
};

C++ 中类和结构之间的唯一区别是其成员的默认可访问性。

于 2012-04-20T05:37:28.043 回答