c ++ - 检查对象是否处于空状态

时间:2016-07-26 22:51:29

标签: c++ object state

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

这是我失败的尝试:

const bool Course::isEmpty() const {
        if (Course() == nullptr) {

            return true;
        }
        else {
            return false;
        }

    }

构造

Course::Course() {
        courseTitle_ = new char[21]; // name
        courseTitle_ = '\0';
        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;
    }

显然,执行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(),因为它失败了。希望我能正确解释。

2 个答案:

答案 0 :(得分:0)

这里最常见的就是你应该做些什么来让测试通过。

在第二个(4参数)构造函数中,对输入进行一些检查,例如检查void calculate(const float *payperhour, const float *hoursworked, float *wage, float *overtime, int p) { if (hoursworked[p] > 40) { overtime[p] = ((hoursworked[p] - 40) * payperhour[p] * 1.5); wage[p] = overtime[p] + (payperhour[p] * 40); } else { overtime[p] = 0; wage[p] = hoursworked[p] * payperhour[p]; } } 是否为正数。检查所有可能出现的错误的所有参数,包括isEmptyTest0..4中的错误。如果有错误,则以与1st(0-argument)构造函数相同的方式初始化对象。如果没有错误,请从参数初始化数据成员。

以下是如何实现credits方法:如果对象的所有数据成员都具有空/零/默认值,则应返回true,如第1(0参数)构造函数初始化。 / p>

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

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

答案 1 :(得分:0)

我同意pts 安全空状态定义不明确。

在阅读评论后,在我看来,缺少的原则是资源获取是初始化RAII)。构造函数是一种事务,在某种程度上:你得到

  • 有效对象,或
  • 例外。

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

中止程序很少是一个选项,并且从构造函数返回错误永远不会。构造无效对象通常仅在禁止例外的环境中进行。

有一种特殊情况:默认构造函数。有时需要“做空”的东西,以后会完全初始化。

考虑std::string。它可以用值构造,如果无法分配内存则抛出异常。或者它可以在没有值的情况下构建,稍后分配一个。你的类可能类似,在这种情况下,安全空只是意味着用户在调用“init”函数时会很乐意销毁的状态。您不必测试每个成员变量;你只需要检查一些只对完全初始化的对象才真实的东西。

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

有一种广泛接受的习惯用于测试对象是否“有效”:用户定义的转换为void *

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

其中is_valid()可能是私有函数。有了这个,用户可以测试他的实例化对象:

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

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