簡體   English   中英

C ++和const - 訪問const引用的成員函數

[英]C++ and const - accessing a member function of a const reference

我在這里有這段代碼。 目的是制作initialData的副本。 由於我沒有以任何方式修改initialData,我認為我應該將它作為const引用傳遞。 但是,我在編譯時不斷收到此消息。

。\\ src \\ Scene \\ SceneAnimationData.cpp(23):錯誤C2662:'SceneTrackerData :: getRect':無法將'this'指針從'const SceneTrackerData'轉換為'SceneTrackerData&'

#include "SceneTrackerData.h"

void SceneAnimationData::SetupData(const SceneTrackerData &initialData)
{
    // getRect(), points() and links() all return const pointers
    CloneRect(initialData.getRect());
    ClonePoints(initialData.points()->values());
    CloneLinks(initialData.links()->values());
}

void SceneAnimationData::CloneRect(const QGraphicsRectItem * initialRect) 
{
    if (initialRect != NULL)
    {
        QPointF position = initialRect->scenePos();
        QRectF rect = initialRect->rect();

        initialRect = new QGraphicsRectItem(rect);
        initialRect->setPos(position);
    }
}

void SceneAnimationData::CloneLinks(const QList<QGraphicsLineItem*> links) 
{
    links_ = new QList<QGraphicsLineItem*>(*links);
}

void SceneAnimationData::ClonePoints(const QList<QGraphicsEllipseItem*> points) 
{
    points_ = new QList<QGraphicsEllipseItem*>(*points);
}

沒有SceneTrackerData的定義,很難說,但函數( SceneTrackerData::getRect )可能沒有標記為const。

那就是(猜測):

const Rect& SceneTrackerData::getRect(void)

應該:

const Rect& SceneTrackerData::getRect(void) const 
                        //                     ^
                        //                     |
                        // does not logically modify the object

目前尚不清楚23號線是哪條; 但我的猜測是你在對象上調用的方法本身並沒有被聲明為const ,因此const對象引用無法使用它們。

我不確定我是不是專家C ++程序員,但是你的函數getRect()等等聲明了const嗎? 如果沒有,但你知道你使用它們的方式是const,你仍然可以使用const_cast從你的initialData引用中刪除const。

例如,請參見: http//docs.oracle.com/cd/E19422-01/819-3690/Cast.html

或Scott Meyers優秀的C ++ - 書籍有效的C ++更有效的C ++ 其中至少有一個有關於constness的項目。

我認為這些行是非法的:

links_ = new QList<QGraphicsLineItem*>(*links);

points_ = new QList<QGraphicsEllipseItem*>(*points);

因為傳入的linkspoints未定義為指針,而是定義的值。 為了編譯代碼,您可能需要像這樣定義它們

const QList<QGraphicsLineItem*>* links

或者,改為像這樣使用它們

links_ = new QList<QGraphicsLineItem*>(&links);  // don't actually do this

但是后者可能是運行時錯誤,因為您正在訪問臨時值的地址,該值在函數體之后消失。

除非QList使用深層復制,否則您的應用很可能會崩潰。

links_ = new QList<QGraphicsLineItem*>(*links);

如果*運算符為QList類重載,這可能是合法的,盡管我認為不是。 雖然如上所述,你可能正在努力做到

links_ = new QList<QGraphicsLineItem*>(links);

取決於實際構造函數的內容。

此外,出於性能原因,這些函數中的每一個都應該通過引用接收QList。 現在,每次調用該函數時,都會復制整個對象兩次。 一旦通過值傳遞它,然后一次用於構建副本。

處理const'ness時要記住的一件事是const不能保證。 存在諸如“const_cast”之類的結構以去除對象的常量。 擁有一個const對象,並使用const函數有助於向其他開發人員表明代碼不應該更改對象,而不是它不能更改它。 看到不同?

void bar(const Foo& f) {
     f.setX(5); // compile error, f is const
     Foo &f2 = const_cast<Foo&>(f);
     f2.setX(5); // compiles just fine
}

有用的部分是無意中嘗試更改對象將導致編譯器錯誤,確定的程序員可以輕松繞過這些保護。

暫無
暫無

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

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