C++ 重写C++;
我的任务是实现一个重写=运算符的方法。我写了一些东西,但老实说,我不知道我在做什么。有人能解释一下这样做的意义吗(不是一般意义上的,我理解,但就在这种情况下,我有点困惑)?我的方法应该实现什么?在当前代码中,我的逻辑在哪里失败C++ 重写C++;,c++,operator-overloading,C++,Operator Overloading,我的任务是实现一个重写=运算符的方法。我写了一些东西,但老实说,我不知道我在做什么。有人能解释一下这样做的意义吗(不是一般意义上的,我理解,但就在这种情况下,我有点困惑)?我的方法应该实现什么?在当前代码中,我的逻辑在哪里失败 scene.cpp:70: error: no match for ‘operator=’ in ‘*(((Image*)(((long unsigned int)i) * 80ul)) + newArray) = *(((Scene*)this)->Scene::
scene.cpp:70: error: no match for ‘operator=’ in ‘*(((Image*)(((long unsigned int)i) * 80ul)) + newArray) = *(((Scene*)this)->Scene::images + ((Image**)(((long unsigned int)i) * 8ul)))’
重写运算符就像现在重载函数一样;您可以通过=op进行复制 Scene A; Scene B; A.do_things(); B = A; 场景A; 场景B; A.做事; B=A;
如果没有重载=运算符;B=A会使B成为指向与A相同的对象的指针(因为C中的类实例变量是指针)。不太确定您希望它做什么。但是它有很多缺点 通常,operator=会复制原件,而不会对原件进行任何更改 这看起来像是要将图像的所有权从一个对象转移到另一个对象 删除*源是危险的,因为它不是/不应该是所有者。源可以很容易地成为堆栈变量 来源!=因此,将图像分配给源只会扼杀一切
将图像存储在向量中可以为您分配内存并复制所有图像。您的代码有一些问题
删除源代码
,您将其作为对const的引用传入,所以不要管它李>
this->images
而不首先删除[]个图像const
图像
分配给源
。一个是你不应该(不能)分配给源代码。另一个是,除非场景
是图像
,否则不能将图像
分配给场景
指针
有一个实现非平凡赋值运算符的规范解决方案:
Scene const & Scene::operator=(Scene s) { swap(s); return *this; }
void Scene::swap(Scene & s) /* nothrow */ {
Image *temp_images = images; images = s.images; s.images = temp_images;
int temp_maximum = maximum; maximum = s.maximum; s.maximum = temp_maximum;
}
这是完全异常安全的,因为它依赖于复制构造函数在交换源(使用无抛出交换)以替换目标之前创建源的临时副本。如果拷贝的任何部分出错,源和目标都将保持原样
它唯一没有做的就是优化自我分配。然而,在自我分配的情况下,它确实能正常工作,我通常不会去优化不应该发生的事情(在实践中,这种情况很少发生)
另一种选择是使用更传统的参数类型:
Scene const & Scene::operator=(Scene const & s) {
Scene temp(s);
swap(temp);
return *this;
}
但是,除了更加冗长之外,这个版本的效率可能更低,因为它保证了复制,而如果传递给s的参数是右值,则传递值版本可能会省略复制。在管理内存的类中实现复制构造函数或赋值运算符是非常棘手的,并确保您的代码异常安全。异常安全意味着,如果在程序中的任何一点引发异常,则确保手动管理的内存仍然正确清理。出现了一些成语来帮助解决这个问题:
std::vector
和tr1::shared\u ptr
等代码来为您进行内存管理。许多知道C++和内存管理古怪的人都经常使用这两种方法。您通常可以仅凭这些就成功。您的(内部)代码在英语中的作用:
//allocate new memory and copy
images = new Image*[source.maximum];
这将images
设置为新分配的源的数组。最大未初始化images
指针。任何图像
指向的内容都将丢失
Scene(source);
这将创建一个新的临时场景
对象,然后将其丢弃。它不会在此
上“重新调用”构造函数
//deallocate old memory
delete *source;
如果有效,这将取消引用source
(这是一个const场景&
,因此只有在定义了T*Scene::operator*(void)
时才有效,其中T
是某种类型)并删除指向T
的对象
//assign
source=images;
这会尝试将图像
复制到源
,这不应该发生,因为源
是常量
。一旦创建,引用就不能更改为引用其他对象
this->maximum=images.maximum;
这不管用<代码>图像
是一个图像**
,它没有最大值
字段。另外,this->
是冗余的
更新:关于新版本:
首先,你不需要到处说this->
for (int i=0;i<source.maximum;i++)
this->images[i]=source->images[i];
这假设您有一个用于Image
(Image::Image(const Image&);
)的复制构造函数
最后,Scene
应该有一个与此类似的复制构造函数,只是它不需要删除旧的内容。如果不复制图像,请使用:
Scene::Scene(const Scene& original): maximum(original.maximum)
{
images = new Image*[maximum];
for(size_t i = 0; i < maximum; i++)
images[i] = source.images[i];
}
Scene::Scene(const Scene& original): maximum(original.maximum)
{
images = new Image*[maximum];
for(size_t i = 0; i < maximum; i++)
images[i] = new Image(*(source.images[i]));
}
Scene::Scene(const Scene&original):最大值(original.max)
{
图像=新图像*[最大值];
对于(尺寸i=0;i<最大值;i++)
images[i]=source.images[i];
}
Scene::Scene(const Scene& original): maximum(original.maximum)
{
images = new Image*[maximum];
for(size_t i = 0; i < maximum; i++)
images[i] = new Image(*(source.images[i]));
}