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

C++ c++;-检查对象是否处于空状态,c++,object,state,C++,Object,State,我需要检查我的对象课程是否处于安全的空状态 以下是我失败的尝试: const bool Course::isEmpty() const { if (Course() == nullptr) { return true; } else { return false; } } 建造商: Course::Course() { courseTitle_ = new

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

以下是我失败的尝试:

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
        );
}

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

这里很可能是让测试通过的方法

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

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

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

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

我同意安全的空状态定义不正确

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

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

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

有一种特殊情况:默认构造函数。有时,我们希望“创建一个空的”东西,稍后完全初始化它

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

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

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

...
public:
  operator void*() { return is_valid()? this : nullptr; }
...
其中
有效()
可能是一个私有函数。有了它,用户可以测试他的实例化对象,因此:

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

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

定义“安全空状态”我猜
中的括号是否(Course()==nullptr)
是个问题。构造一个空的Course对象,然后再次测试它。我不太确定您打算做什么,但可能不是这个。
courseTitle_uu0'应该是
CourseTile_u0]='\0'。您正在用char-literal的地址覆盖新的
char数组的地址。这会导致内存泄漏,很可能是后来的一个分割错误。@ ANDIRW1990 1990 C++不是java、C或JavaScript。你还不明白C++中的事情是如何完成的。其中一个主要原因是“在线教科书”很糟糕。你不想解决你自己的问题。相反,你想后退一步,正确地学习C++。对于我来说,看起来代码< >空> <代码>应该测试一个有效的状态。前四个测试都将一个无效值作为构造函数参数之一传递,并期望得到一个“坏/空”的课程对象。尝试了它,但没有成功。它仍然无法通过测试(),感谢您发布代码!你的做法与我的建议不同。我建议:即使只有1个参数出错,所有参数都应该设置为空。如果修复后仍然失败,而你无法找出原因,我认为你应该发布一个单独的任务