C ++和const - 访问const引用的成员函数

时间:2009-08-17 06:20:52

标签: c++ const

我这里有这段代码。目的是制作initialData的副本。由于我没有以任何方式修改initialData,我认为我应该将它作为const引用传递。但是,我在编译时不断收到此消息。

  

。\ SRC \场景\ 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);
}

5 个答案:

答案 0 :(得分:13)

如果没有SceneTrackerData的定义,很难说,但函数(SceneTrackerData::getRect)很可能没​​有标记为const。

那就是(猜测):

const Rect& SceneTrackerData::getRect(void)

应该是:

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

答案 1 :(得分:1)

目前尚不清楚23号线是哪条;但我的猜测是你在对象上调用的方法本身并没有被声明为const,因此const对象引用无法使用它们。

答案 2 :(得分:1)

我不确定我是不是专家C ++程序员,但是你的函数getRect()等等声明了const吗?如果没有,但你知道你使用它们的方式是const,你仍然可以使用const_cast从你的initialData引用中删除const。

例如,请参见:http://docs.oracle.com/cd/E19422-01/819-3690/Cast.html

或Scott Meyers优秀的C ++ - 图书 Effective C++ More Effective C++ 。其中至少有一个有关于constness的项目。

答案 3 :(得分:1)

我认为这些行是非法的:

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使用深层复制,否则您的应用很可能会崩溃。

答案 4 :(得分:0)

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
}

有用的部分是无意中尝试更改对象将导致编译器错误,确定的程序员可以轻松绕过这些保护。