简体   繁体   English

PIMPL const正确性

[英]PIMPL const correctness

.h 。H

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

.cpp 的.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 。H

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

.cpp 的.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 。H

#include <PrivatePtr.h>

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

.cpp 的.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' 但这会导致C4251“myclass :: d:class'PrivatePtr'需要让clas'myclass'的客户端使用dll-interface

Wait, what? 等等,什么? I DON'T want it to be used by anyone but myclass internally... safe to ignore? 我不希望任何人使用它,但内部的myclass ...安全忽略? 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. 在其他情况下,它似乎确实有点问题。

You can hide d behind an accessor function, and overload that based on const . 您可以隐藏访问者函数后面的d ,并基于const重载。 Instead of accessing d directly, you then write impl()->count = 2; 而不是直接访问d ,然后编写impl()->count = 2; . impl() would return Private * , whereas impl() const would return const Private * . impl()将返回Private * ,而impl() const将返回const Private *

.h 。H

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

.cpp 的.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 。H

#include <PrivatePtr.h>

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

.cpp 的.cpp

#include <PrivatePtr.cpp>

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

Instead of marking the entire class for export, only mark the functions you intend on using through the dll. 不是将整个类标记为导出,而是仅通过dll标记要使用的函数。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM