我正在尝试了解PIMPL习惯用法和一般的c++。

我有一个带有PIMPL样式接口(interface)的类,该类将int值设置为7。但是,当我打印它时,我得到了一个垃圾值,我不明白为什么。

代码

Test.cpp

#include <iostream>
#include "Test.h"
struct Foo::Bar
{
    int value;
};

Foo::Foo()
{
    Bar tempBar;
    myBar = &tempBar;
    myBar->value = 7;
}
void Foo::printValue()
{
    std::cout << "Value = " << myBar->value << std::endl;
}
int main()
{
    Foo myFoo;
    myFoo.printValue();
    return 0;
}

Test.h
class Foo
{
    private:
        struct Bar;
        Bar* myBar;
    public:
        Foo();
        void printValue();
        //~Foo();
};

输出

值(value)= 2147120498

最佳答案

mybarFoo构造函数内部的局部变量的指针。当构造函数退出时,变量消失了,但是myBar仍然指向旧内存。

由于要实现PIMPL,实际上只有一种选择。您需要使用myBar动态分配new,并在delete析构函数中使用Foo释放它。您还必须向Foo中添加一个副本构造函数和一个副本赋值运算符,以避免内存泄漏:

测试文件

Foo::Foo()
{
    myBar = new Bar;
    myBar->value = 7;
}

Foo::Foo(const Foo &src)
{
    myBar = new Bar;
    *myBar = *(src.myBar);
}

Foo::~Foo()
{
    delete myBar;
}

Foo& Foo::operator=(const Foo &rhs)
{
    *myBar = *(rhs.myBar);
    return *this;
}

测试
class Foo
{
private:
    struct Bar;
    Bar* myBar;
public:
    Foo();
    Foo(const Foo &src);
    ~Foo();

    void printValue();

    Foo& operator=(const Foo &rhs);
};

如果您未实现PIMPL,那么将有另一种选择。使myBar成为Foo类的非指针成员:

测试文件
Foo::Foo()
{
    myBar.value = 7;
}

void Foo::printValue()
{
    std::cout << "Value = " << myBar.value << std::endl;
}

测试
class Foo
{
private:
    struct Bar
    {
        int value;
    };

    Bar myBar;

public:
    Foo();
    void printValue();
};

关于c++ - 为什么在打印值时会得到垃圾值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36586488/

10-10 01:03