PIMPL const正确性

时间:2013-11-04 12:14:50

标签: c++ pimpl-idiom

·H

public:
    void doStuff() const;
private:
    struct Private;
    Private * d;

的.cpp

struct XX::Private
{
    int count;
}

void XX::doStuff() const
{
    d->count = 2; // I want an error here!!
}

你需要更深入的解释吗?

更新

我认为我会做一些不同的事情,需要对代码进行少量更改。我做了这个:

·H

template <class TPriv>
class PrivatePtr
{
    public:
        ...
        TPriv * const operator->();
        TPriv const * const operator->() const;
        ...
    private:
        TPriv * m_priv;
};

的.cpp

...

template <class TPriv>
TPriv * const PrivatePtr<TPriv>::operator->()
{
    return m_priv;
}

template <class TPriv>
TPriv const * const PrivatePtr<TPriv>::operator->() const
{
    return m_priv;
}

然后像这样使用它:

·H

#include <PrivatePtr.h>

class DLLEXPORTMACROTHING myclass
{
    ...
    private:
        struct Private;
        PrivatePtr<Private> d;
};

的.cpp

#include <PrivatePtr.cpp>

struct myclass::Private()
{
    ...
}

但是这会导致C4251“myclass :: d:class'PrivatePtr'需要让clas'myclass'的客户端使用dll-interface

等等,什么?我不希望任何人使用它,但内部的myclass ...安全忽略?我试着寻找答案,但没有一个案例接近我在这里的情况。在其他情况下,它似乎确实有点问题。

3 个答案:

答案 0 :(得分:7)

您可以隐藏d隐藏在访问者函数后面,并根据const重载该函数。您可以编写d,而不是直接访问impl()->count = 2;impl()会返回Private *,而impl() const会返回const Private *

答案 1 :(得分:2)

·H

template <class TPriv>
class PrivatePtr
{
    public:
        ...
        TPriv * const operator->();
        TPriv const * const operator->() const;
        ...
    private:
        TPriv * m_priv;
};

的.cpp

...

template <class TPriv>
TPriv * const PrivatePtr<TPriv>::operator->()
{
    return m_priv;
}

template <class TPriv>
TPriv const * const PrivatePtr<TPriv>::operator->() const
{
    return m_priv;
}

然后像这样使用它:

·H

#include <PrivatePtr.h>

class DLLEXPORTMACROTHING myclass
{
    ...
    private:
        struct Private;
        PrivatePtr<Private> d;
};

的.cpp

#include <PrivatePtr.cpp>

struct myclass::Private()
{
    ...
}

答案 2 :(得分:0)

不是将整个类标记为导出,而是仅通过dll标记要使用的函数。

class myclass
{
public:
    DLLEXPORTMACROTHING myclass();
    DLLEXPORTMACROTHING ~myclass();

    DLLEXPORTMACROTHING void myfunction();
...
private:
    struct Private;
    PrivatePtr<Private> d;
};