MST
星途 面试题库

面试题:C++ 类成员初始化异常处理的常见方式

在 C++ 中,当类成员初始化可能抛出异常时,有哪些常见的异常处理方式?请举例说明如何在构造函数中处理成员初始化抛出的异常。
11.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

在C++中,当类成员初始化可能抛出异常时,常见的异常处理方式有以下几种:

1. 在构造函数体中捕获异常

#include <iostream>
#include <stdexcept>

class SubClass {
public:
    SubClass(int value) {
        if (value < 0) {
            throw std::invalid_argument("Negative value not allowed");
        }
        // 正常初始化逻辑
    }
};

class MainClass {
private:
    SubClass subObj;
public:
    MainClass(int value) {
        try {
            subObj = SubClass(value);
        } catch (const std::invalid_argument& e) {
            std::cerr << "Caught in MainClass constructor: " << e.what() << std::endl;
            // 可以在这里进行一些错误处理,例如设置默认值等
        }
    }
};

2. 使用初始化列表并让异常向上传递

#include <iostream>
#include <stdexcept>

class SubClass {
public:
    SubClass(int value) {
        if (value < 0) {
            throw std::invalid_argument("Negative value not allowed");
        }
        // 正常初始化逻辑
    }
};

class MainClass {
private:
    SubClass subObj;
public:
    MainClass(int value) : subObj(value) {
        // 构造函数体为空,异常会直接从subObj的构造函数向上传递
    }
};

int main() {
    try {
        MainClass obj(-1);
    } catch (const std::invalid_argument& e) {
        std::cerr << "Caught in main: " << e.what() << std::endl;
    }
    return 0;
}

3. 使用智能指针管理资源(适用于动态分配成员)

#include <iostream>
#include <memory>
#include <stdexcept>

class Resource {
public:
    Resource(int value) {
        if (value < 0) {
            throw std::invalid_argument("Negative value not allowed");
        }
        std::cout << "Resource initialized successfully" << std::endl;
    }
    ~Resource() {
        std::cout << "Resource destroyed" << std::endl;
    }
};

class Container {
private:
    std::unique_ptr<Resource> resPtr;
public:
    Container(int value) {
        try {
            resPtr.reset(new Resource(value));
        } catch (const std::invalid_argument& e) {
            std::cerr << "Caught in Container constructor: " << e.what() << std::endl;
            // 可以进行其他处理,例如设置resPtr为一个默认状态
        }
    }
};

以上这些方式可以根据具体的需求和场景选择使用,以妥善处理类成员初始化过程中可能抛出的异常。