4

.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' needs to have dll-interface to be used by client of clas 'myclass' が発生します。

待って、何?内部で myclass 以外の誰にも使用されたくない...無視しても安全ですか? 答えを探してみましたが、ここにあるものに近いケースはありませんでした。他のケースでは、それはかなりの問題のように思えました。

4

3 に答える 3

7

アクセサー関数の背後に隠れdて、に基づいてオーバーロードできconstます。d直接アクセスする代わりに、次のように記述しimpl()->count = 2;ます。impl()を返しますPrivate *が、impl() constを返しconst Private *ます。

于 2013-11-04T12:19:19.007 に答える
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()
{
    ...
}
于 2014-03-04T11:24:47.147 に答える