从 std::string 初始化派生类的复制构造函数

Initialize copy constructor of a derived class from std::string

提问人:J Laurent 提问时间:3/25/2020 更新时间:3/26/2020 访问量:58

问:

当我从 std::string 派生一个 String 类并对其进行测试时,我遇到了一个问题。

下面是 String 类:

namespace Types
{

class String : public std::string
{
public:
    String();

    /*!
     * @fn String(const String &other);
     * @brief Copy contructor
     * @param other
     */
    String(const String &other)
        : std::string(other) {}
    String(const char* format_string, ...);

    virtual ~String();
};

} /* namespace Types */

这是测试类:

class String_test : public CppUnit::TestFixture
{
    CPPUNIT_TEST_SUITE(String_test);
    CPPUNIT_TEST(testCopyConstructor);
    CPPUNIT_TEST_SUITE_END();

public:
    void setUp(void)
    {
        mTestObj = new Types::String();
    }
    void tearDown(void)
    {
        delete mTestObj;
    }

protected:
    void testCopyConstructor(void)
    {
        *mTestObj = "toto";
        std::cout << *mTestObj << std::endl;
        Types::String new_string((const Types::String&)mTestObj);
        CPPUNIT_ASSERT(true == true);
    }
private:
    Types::String *mTestObj;
};

编译正常,但是当程序运行时,我遇到此错误:

##Failure Location unknown## : Error
Test name: String_test::testCopyConstructor
uncaught exception of type std::exception (or derived).
- basic_string::_M_construct null not valid

我已经搜索了有关复制构造函数和派生类的文档,似乎在代码中没问题。 我不明白有什么问题。

有人有想法吗?

谢谢

C++ 复制 复制构造函数

评论

3赞 RoQuOTriX 3/25/2020
stackoverflow.com/questions/6006860/......从字符串派生是不好的做法
0赞 François Andrieux 3/25/2020
您可能打算使用 而不是 .避免 C 风格的强制转换,它们可以让你将各种东西投射到其他不应该被强制转换的东西上。如果添加一个可以修复编译器错误,大多数时候它只是向您隐藏它,而没有实际修复任何内容。*mTestObj(const Types::String&)mTestObj
1赞 463035818_is_not_an_ai 3/26/2020
一般来说,从标准类型公开继承是一个坏主意。私下继承是可以的,但你不妨使用组合而不是继承。

答:

1赞 walnut 3/26/2020 #1

mTestObj是一个指针,所以

(const Types::String&)mTestObj

不能解释为 ,因为没有 的构造函数 需要 .static_cast<const Types::String&>(mTestObj)Types::StringTypes::String*

所以它将被解释为

 reinterpret_cast<const Types::String&>(mTestObj)

其含义与

 *reinterpret_cast<const Types::String*>(&mTestObj)

由于 (指针) 的地址处没有对象,因此访问此强制转换的结果(就好像存在)会导致未定义的行为。这发生在复制构造函数中。或者,如果 的对齐方式不匹配,则强制转换的结果可能已未指定。Types::StringmTestObjstd::stringTypes::String

不要使用 C 型演员,因为您可以看到它们非常危险。

您可以使用以下命令从指针获取引用,并且可以通过调用该指针来获取引用:*conststd::as_const

Types::String new_string(std::as_const(*mTestObj));

虽然我不确定你为什么首先需要,所以可能你真的想要只是const

Types::String new_string(*mTestObj);