正在检查对象是否处于空状态

Checking if an Object is in empty state

本文关键字:于空 状态 是否 对象 检查      更新时间:2023-10-16

我需要检查我的对象Course是否处于安全的空状态。

这是我失败的尝试:

const bool Course::isEmpty() const {
        if (Course() == nullptr) {
            return true;
        }
        else {
            return false;
        }
    }

施工单位:

Course::Course() {
        courseTitle_ = new char[21]; // name
        courseTitle_ = '';
        credits_ = 0;//qtyNeeded
        studyLoad_ = 0;//quantity

        strcpy(courseCode_, "");//sku
    }
    Course::Course(const char* courseCode, const char* courseTitle, int credits , int studyLoad ) {
        strcpy(courseCode_, courseCode);
        courseTitle_ = new char[21];
        strcpy(courseTitle_, courseTitle);
        studyLoad_ = studyLoad;
        credits_ = credits;
    }

显然,Doing course()==nullptr并不是真正检查对象是否处于安全的空状态,如果单个变量设置为0,也检查它们在我的程序中不起作用。我需要检查整个对象是否设置为安全的空状态。

编辑:你们中的一些人在问我的empty()函数应该使用什么。假设有一个测试程序来测试我的isEmpty()是否工作良好。

bool isEmptyTest0() {
    // empty test
    sict::Course c0;
    return c0.isEmpty();
}
bool isEmptyTest1() {
    // empty test
    sict::Course c0("", "title", 3, 3);
    return c0.isEmpty();
}
bool isEmptyTest2() {
    // empty test
    sict::Course c0("code", "", 3, 3);
    return c0.isEmpty();
}
bool isEmptyTest3() {
    // empty test
    sict::Course c0("code", "title", -1, 3);
    return c0.isEmpty();
}
bool isEmptyTest4() {
    // empty test
    sict::Course c0("code", "title", 3, -1);
    return c0.isEmpty();
}
bool regularInitTest() {
    // regular
    sict::Course c5("OOP244", "Object-Oriented Programming in C++", 1, 4);
    return (!c5.isEmpty()
        && !strcmp("OOP244", c5.getCourseCode())
        && !strcmp("Object-Oriented Programming in C++", c5.getCourseTitle())
        && (c5.getCredits() == 1)
        && c5.getStudyLoad() == 4
        );
}

请注意,在regularInitTest()中,我的赋值运算符工作得很好,但它从未通过!c5.isEmpty(),因为它失败了。希望我解释的正确。

这里很可能是您应该做些什么来通过测试。

在第二个(4参数)构造函数中,对输入进行一些检查,例如检查credits是否为正。请检查所有参数中所有可能出现的错误,包括isEmptyTest0..4中的错误。如果出现错误,请以与第一个(0参数)构造函数相同的方式初始化对象。如果没有错误,请从参数初始化数据成员。

以下是如何实现isEmpty方法:当对象的所有数据成员都具有空/零/默认值时,它应该返回true,由第一个(0参数)构造函数初始化。

安全空状态的概念本身仍然没有意义,但教授试图教授的概念确实有意义。我将在这里总结一下我的理解。构造函数可以接收无效的参数,基于这些参数不可能初始化有意义的有效对象。程序员应该在程序中的任何地方添加用于错误检查和处理的代码,包括构造函数。有多种方法可以在构造函数中进行输入验证和错误处理,例如1。抛出异常;2.用错误消息中止整个程序;3.将对象初始化为特殊的无效状态;4.将对象初始化为一个特殊的空状态。(这也是一个选项,但强烈建议不要使用:5。保持对象的某些数据成员未初始化。)这些方法各有利弊。在这项作业中,教授希望你实施#4。请参阅我的答案中的第2段。

当教授要求安全的空状态时,他很可能意味着你应该在构造函数中进行输入验证,如果出现错误,请执行#4而不是#5。

我同意pts的观点,即安全空状态定义不周。

在阅读了评论后,我觉得缺少的原则是资源获取是初始化(RAII)。构造函数在某种程度上是一个事务:您可以获得

  • 有效对象,或
  • 一个例外

此处的有效由类定义。通常,这意味着传递的参数被合并到对象中,并且所有所需的资源都被成功分配和/或找到。

中止程序很少是一种选择,返回错误(来自构造函数)也从来不是。构造无效对象通常只在禁止异常的环境中进行。

有一种特殊情况:默认构造函数。有时,我们希望"制作一个空的"东西,稍后将完全初始化。

考虑std::string。它可以用一个值构造,如果无法分配内存,则抛出异常。或者,它可以在没有值的情况下构造,然后指定一个值。您的类可能是类似的,在这种情况下,safe-empty只意味着用户在调用"init"函数时愿意破坏的状态。您不必测试每个成员变量;你只需要检查一个只有完全初始化的对象才会为真的东西。

然后是"是否有效"的问题。"空"对象可以"初始化",但不能使用。在完全初始化之前,无论是在构造时,还是通过具有默认构造函数和后续"init"的两步操作,它都不能"有效"使用。

有一个被广泛接受的习惯用法用于测试对象是否"有效":用户定义的到void *:的转换

...
public:
  operator void*() { return is_valid()? this : nullptr; }
...

其中CCD_ 8可以是私有功能。有了它,用户就可以测试他的实例化对象了:

class A;
A foo();
...
if (!foo) { foo.open(...); }

我知道我还没有回答你的问题。我希望我提供了一些背景知识,让你自己更容易回答。