2014-05-12 91 views
5

对不起,对于这个非常晦涩难懂的标题,但它确实有点说明一切。这就是我的意思防止const类函数在引用成员上调用非const类的函数

class A 
{ 
    void DoSomething(); // non-const 
} 
Class B 
{ 
public: 
    B(A& a) : _a(a) { } 
    // const function 
    void DoSomethingElse() const 
    { 
     // Is there a way to disallow this? 
     _a.DoSomething(); 
    } 
    void DoEvenMore() 
    { 
     // Should be OK 
     _a.DoSomething(); 
    } 
private: 
    // Can't make it const A& because it needs 
    // be non-const for non-const functions 
    A& _a; // A reference 
} 

那么,有没有办法可以阻止B::DoSomethingElse()与调用A::DoSomething()
但是,B::DoEventMore()不是const应该能够继续呼叫。

我使用Visual C++ 2013年

上面的代码会证明我的程序中的错误。 (在我的场景中,类A会卸载调用代码的对象/ this指针。)由于const正确性的要点是防止这种类型的错误,所以我只是想知道在编译时是否有办法检查这个错误。

在应用程序中,我正在编写该函数根本不会有任何危险。当从DoEvenMore()调用它时,结果将是相同的,除了B的销毁被推迟到功能完成运行为止。

回答

9

而不是使用_a数据成员直接创建访问器函数与const和非const重载。当从const成员函数B中调用const时,会导致const过载被选中,从而阻止您调用A的非const函数。

A const& GetA() const { return _a; } 
A& GetA() { return _a; } 


void DoSomethingElse() const 
{ 
    GetA().DoSomething(); // error 
} 
+0

谢谢,这就是我一直在寻找的。没有办法让它隐含,对吧? (省略通话。) – Aidiakapi

+0

@Aidiakapi如果您的意思是直接访问'_a',那么不会。由于'_a'本身不是'const',因此可以使用它自由地调用非''constst'成员函数。 – Praetorian

+0

好的,谢谢你的回答。 – Aidiakapi

5

“constness”规则使对象本身不可改变,但不影响指向/被引用对象的常量。如果要使用const方法访问const参考仅限,则需要在constness上创建一个重载方法,该方法返回一个引用或一个const引用。

class B { 
private: 
    inline A& a() { return _a; } 
    inline const A& a() const { return _a; } 
public: 
    // ... 
};