簡體   English   中英

這會導致無限循環嗎?

[英]Might this cause an infinite loop?

對於定義const的第二個const版本,是否可以保證這樣做安全? 當我想返回const它似乎將具有無限遞歸,但是我要調用的另一個函數是非const。

它適用於g ++,但我擔心這是不安全的。

#include <iostream>

using namespace std;

class test {
public:
   int* doSomething(int a) {
      int* someInt = new int(a);

      return someInt;
   }

   const int* doSomething(int a) const {
      return doSomething(a);
   }
};

int main() {
   test a;

   cout << *a.doSomething(12345) << endl;

   return 1;
}

不完全是:正如@Pete Becker在評論中指出的,如果您調用了遞歸的const版本:

class test {
public:
   int* doSomething(int a) {
      int* someInt = new int;
      *someInt = a;
      return someInt;
   }

   const int* doSomething(int a) const {
      return doSomething(a);
   }
};

int main() {
   const test a;
   // You're not in for a good time:
   a.doSomething(12345);
   return 1;
}

當提供需要重復代碼的函數的const和非const版本時,最好實現const版本,然后以特定的方式調用non- const版本。

來自Scott Myers Effective C ++-第三版

const和非const成員函數具有基本相同的實現時,可以通過使非const版本調用const版本來避免代碼重復。

斯科特·邁爾斯(Scott Myers)繼續為此提供了一種安全的方法:

const int* doSomething(int a) const
{
   int* someInt = new int;
   *someInt = a;
   return someInt;
}

int* doSomething(int a)
{
   return const_cast<int*>(static_cast<const Test&>(*this).doSomething());
}

在非const版本中,有兩種強制轉換: static_cast基本上將this轉換為const this ,其中const_cast強制放棄返回的const -ness。 這是安全的,因為要調用非const版本,您必須具有非const this

但是,如果您僅提供對成員的訪問權限,則只需具有以下內容即可輕松閱讀:

class TestAccess;
class Test
{
    TestAccess& t;
public:
    const TestAccess& getA() const { return t; }
    TestAcess& getA() { return t; }
};

在這種情況下,編譯器總是選擇函數的非const版本,甚至不調用const版本。 否則,編譯器將無法編譯,您正在竭盡全力。 例如,我快速修改了代碼:

#include <iostream>

using namespace std;

class test {
public:
    int* doSomething(int a) {
        int* someInt = new int;

        *someInt = a;
        return someInt;
    }
    int ax = 10;
    void somethingElse(int i)
    {
        ax = i;
    }
    const int* doSomething(int a) const {
        somethingElse(a);
        return 0;
    }
};

int main() {
    test a;

    cout << *a.doSomething(12345) << endl;

    return 1;
}

該示例無法編譯,因為您正在const范圍內調用const函數。 編譯器不允許您這樣做。

現在,我知道這是一個測試,但是這樣做將永遠不會退出遞歸,它將永遠循環,而且每次調用都會通過在堆上分配內存來泄漏內存,這兩種情況共同導致災難。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM