Вопрос

.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!!
}

Do you need furher explanation?

Update:

I thought I'd do something a bit different that requires less changes to the code. I made this:

.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;
}

And then use it like this:

.h

#include <PrivatePtr.h>

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

.cpp

#include <PrivatePtr.cpp>

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

But this causes C4251 "myclass::d : class 'PrivatePtr' needs to have dll-interface to be used by clients of clas 'myclass'

Wait, what? I DON'T want it to be used by anyone but myclass internally... safe to ignore? I tried looking for the answer but none of the cases were close to what I have here. On the other cases it did seems like quite a bit issue.

Это было полезно?

Решение 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;
}

And then use it like this:

.h

#include <PrivatePtr.h>

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

.cpp

#include <PrivatePtr.cpp>

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

Другие советы

You can hide d behind an accessor function, and overload that based on const. Instead of accessing d directly, you then write impl()->count = 2;. impl() would return Private *, whereas impl() const would return const Private *.

Instead of marking the entire class for export, only mark the functions you intend on using through the dll.

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

    DLLEXPORTMACROTHING void myfunction();
...
private:
    struct Private;
    PrivatePtr<Private> d;
};
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top