我这里有这段代码。目的是制作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);
}
答案 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);
因为传入的links
和points
未定义为指针,而是定义的值。为了编译代码,您可能需要像这样定义它们
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
}
有用的部分是无意中尝试更改对象将导致编译器错误,确定的程序员可以轻松绕过这些保护。