2013-11-04 92 views
3

.HPIMPL const正確性

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

你需要furher解釋?

更新:

我想我會做到這一點,需要的代碼少變化的東西有點不同。我做了這個:

.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:類 'PrivatePtr' 需要有DLL接口由CLAS 'MyClass的'

等等,你的客戶端使用?我不希望它被任何人使用,除了myclass內部...安全地忽略?我試圖尋找答案,但沒有任何案例接近我在這裏。在其他情況下,它確實似乎有點問題。

+2

我愛你對問題的解釋。 –

+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() 
{ 
    ... 
} 
7

您可以將d隱藏在訪問器函數後面,並根據const來重載。直接訪問d,然後寫impl()->count = 2;impl()將返回Private *,而impl() const將返回const Private *

+0

幾乎我想要的。我仍然需要阻止直接訪問成員變量。好的建議,但! – 0xbaadf00d

+2

@justanothercoder將它重命名爲'_d_dont_use_directly',並擊中任何直接使用它的人。:)更嚴重的是,你可以使成員變量本身爲'const Private *',並且在非const的impl()函數中,使用'const_cast'。這應該可以防止意外誤用。 – hvd

+0

您還必須刪除拷貝構造函數,否則可以將const XX拷貝到非常量拷貝中,然後使用非常量成員functoins。 –

0

而不是標記整個類的輸出,只能通過dll標記你打算使用的函數。

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

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

抱歉,這與答案無關。我甚至不知道爲什麼我把宏放在那裏,也許有點不對,但我實在不記得了。 – 0xbaadf00d

+0

我意識到這不是對原始問題的回答,而是認爲將它添加進去會很好。也許它會更好地作爲評論... – Lambage