粉刺不工作

发布于 2024-09-28 17:32:10 字数 615 浏览 4 评论 0原文

这是一个非常菜鸟的错误,但我不知道这里发生了什么。

有很多 pimpl 示例,但我不明白为什么这不起作用(这或多或少是示例之一,但我没有看到区别)。

我有一个非常简单的 Pimpl 示例,但它不起作用。

// Foo.hpp
#include <boost/scoped_ptr.hpp>

class Foo
{
 struct Bar;
 //boost::scoped_ptr<Bar> pImpl;
 Bar* pImpl;

public:
 Foo();
 ~Foo() {}

 int returnValue();

private:

};

编译

// Foo.cpp
#include "foo.hpp"

struct Foo::Bar
{ 
 Bar() {}
 ~Bar() {}
 int value;
};

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

int Foo::returnValue() {
 return *pImpl->value;
}

这个给了我错误。 C2100:非法间接。

谢谢。

This is a very noobish mistake, but I dont know whats happening here.

There are loads of pimpl examples but I dont understand why this isn't working (this was one of the examples more or less but I dont see the difference).

I have a very simple Pimpl example, but it wont work.

// Foo.hpp
#include <boost/scoped_ptr.hpp>

class Foo
{
 struct Bar;
 //boost::scoped_ptr<Bar> pImpl;
 Bar* pImpl;

public:
 Foo();
 ~Foo() {}

 int returnValue();

private:

};

and

// Foo.cpp
#include "foo.hpp"

struct Foo::Bar
{ 
 Bar() {}
 ~Bar() {}
 int value;
};

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

int Foo::returnValue() {
 return *pImpl->value;
}

Compiling this gives me the error.
C2100: illegal indirection.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱已欠费 2024-10-05 17:32:10

int returnValue() 应该是一个成员函数:

//  vvvvv
int Foo::returnValue() {
 return pImpl->value; // no need to dereference, value isn't a pointer
}

您需要在定义实现类之后定义构造函数、复制构造函数、复制赋值运算符和析构函数。 (否则隐式析构函数是危险的,并且 scoped_ptr 不会让你这样做):

// Foo.hpp
#include <boost/scoped_ptr.hpp>

class Foo
{
    struct Bar;
    boost::scoped_ptr<Bar> pImpl;

public:
    Foo();
    ~Foo();

    int returnValue(); // could be const (so should be)

private:
    // just disable copying, like scoped_ptr
    Foo(const Foo&); // not defined
    Foo& operator=(const Foo&); // not defined
};

并且:

// Foo.cpp
#include "foo.hpp"

struct Foo::Bar
{ 
    int value;
};

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

Foo::~Foo()
{
    // okay, Bar defined at this point; scoped_ptr can work
}

int Foo::returnValue()
{
    return pImpl->value;
}

int returnValue() should be a member function:

//  vvvvv
int Foo::returnValue() {
 return pImpl->value; // no need to dereference, value isn't a pointer
}

You need to define your constructor, copy-constructor, copy assignment operator, and destructor after the implementation class has been defined. (Otherwise the implicit destructor is dangerous, and scoped_ptr won't let you do that):

// Foo.hpp
#include <boost/scoped_ptr.hpp>

class Foo
{
    struct Bar;
    boost::scoped_ptr<Bar> pImpl;

public:
    Foo();
    ~Foo();

    int returnValue(); // could be const (so should be)

private:
    // just disable copying, like scoped_ptr
    Foo(const Foo&); // not defined
    Foo& operator=(const Foo&); // not defined
};

And:

// Foo.cpp
#include "foo.hpp"

struct Foo::Bar
{ 
    int value;
};

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

Foo::~Foo()
{
    // okay, Bar defined at this point; scoped_ptr can work
}

int Foo::returnValue()
{
    return pImpl->value;
}
网白 2024-10-05 17:32:10

顺便说一句,您可能会在 pImpl 中使用 boost::scoped_ptr 时遇到问题,因为您的 pImpl 是向前声明的,并且您可能会发现该类需要完全可见才能调用scoped_ptr 的析构函数(删除底层)。

某些编译器允许您通过将析构函数的主体放入类可见的编译单元(.cpp 文件)中来解决此问题。

最简单的解决方案是,如果您的析构函数无论如何都必须实现,您也可以只使用原始指针并让析构函数删除它。如果您想使用 boost 中的某些东西来帮助您,请从 boost::noncopyable 派生您的外部类。否则请确保正确处理复制构造和分配。

您可以将shared_ptr 用于您的pImpl。然后,您可以愉快地复制外部类,尽管它们共享相同的底层,除非您重载复制构造函数和赋值运算符以执行其他操作。

As an aside, you may have a problem using boost::scoped_ptr for a pImpl because your pImpl is forwardly declared and you may find that the class needs to be fully visible in order to call scoped_ptr's destructor (which deletes the underlying).

Some compilers will allow you to work around this by putting the body of your destructor in the compilation unit (the .cpp file) where the class is visible.

The simplest solution is that if your destructor has to be implemented anyway you may as well just use a raw pointer and have your destructor delete it. And if you want to use something from boost to help you, derive your outer class from boost::noncopyable. Otherwise ensure you handle copy-construction and assignment properly.

You can use shared_ptr to your pImpl. You can then copy your outer class around happily although they share the same underlying unless you overload the copy-constructor and assignment operator to do otherwise.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文