Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使子类在虚拟方法中返回自身的对象(副本)_C++_Templates_Inheritance_Vector_Covariant Return Types - Fatal编程技术网

C++ 如何使子类在虚拟方法中返回自身的对象(副本)

C++ 如何使子类在虚拟方法中返回自身的对象(副本),c++,templates,inheritance,vector,covariant-return-types,C++,Templates,Inheritance,Vector,Covariant Return Types,我目前正试图理解C++中的继承,但我很困惑,为什么我不能让我的主类的子类返回一个与我从载的一些操作符方法中的子类相同的对象。 这些类的定义如下(这是一个简化版本): 模板 类向量 { 公众: Vect()=默认值; 虚拟向量运算符+(常量&); 虚拟向量算子-(常量&); } 模板 类向量固定:公共向量 { 公众: Vect_fixe()=默认值; 虚拟向量固定算子+(常量&); 虚拟向量固定算子-(常量&); 私人: elem-vecteur[taille]={0}; } 这些方法就是这样定

我目前正试图理解C++中的继承,但我很困惑,为什么我不能让我的主类的子类返回一个与我从载的一些操作符方法中的子类相同的对象。 这些类的定义如下(这是一个简化版本):

模板
类向量
{
公众:
Vect()=默认值;
虚拟向量运算符+(常量&);
虚拟向量算子-(常量&);
}
模板
类向量固定:公共向量
{
公众:
Vect_fixe()=默认值;
虚拟向量固定算子+(常量&);
虚拟向量固定算子-(常量&);
私人:
elem-vecteur[taille]={0};
}
这些方法就是这样定义的:

template <class elem, std::size_t taille>
Vect_fixe<elem,taille> Vect_fixe<elem, taille>::operator+(const elem& operand)
{
    Vect_fixe<elem, taille> temp_v;
    for (int i=0; i<taille; i++)
        {
        temp_v[i] = vecteur[i];
        temp_v[i] += operand;
        }
    return temp_v;
}

template <class elem, std::size_t taille>
Vect_fixe<elem,taille> Vect_fixe<elem, taille>::operator-(const elem& operand)
{
    Vect_fixe<elem, taille> temp_v;
    for (int i=0; i<taille; i++)
        {
        temp_v[i] = vecteur[i];
        temp_v[i] -= operand;
        }
    return temp_v;
模板
向量固定向量固定::运算符+(常量元素和操作数)
{
向量固定温度;

对于(int i=0;i我可以指出的一件事是,您没有按照您想要的方式进行继承。我可以猜您的意图是使用
Vect
作为接口,并用
Vect\u fixe
覆盖它

但是,由于返回类型不同,它们成为协变返回类型。这种机制要求通过指针或引用返回(因此协变类型可以相互转换)

如果您打算使用
Vect
作为其所有子类型的通用引用处理程序,那么您实际上应该返回引用/指针

我尝试使用引用来执行此操作,但就我所知,返回对临时对象的引用是未定义的行为,我希望这些方法返回我的对象的副本,而不是直接修改它

如果返回引用,则可以使用
static
local来延长其生存期

int& returnByReference()
{
     static int x = 5; // static ensures x doesn't go out of scope when we return it by reference
     return x;
}

int value = returnByReference(); // case A -- ok, treated as return by value
const int &cref = returnByValue(); // case C -- ok, the lifetime of return value is extended to the lifetime of cref

但这不是一个好主意。正如@n.m.在文章中所说,继承和复制不能很好地结合,因为重载最终会导致歧义或不可避免但不希望的强制转换。

继承和复制不能很好地结合,我建议您在“试图理解C++中的继承”时不要尝试这种方法如果你想尝试它,你应该知道你必须返回一个引用或指针。在实践中,这意味着你必须返回一个指针,你必须在空闲存储区上分配结果,并且从现在起你必须管理它的生命周期。这不是一个非常新手友好的命题,但这就是我们在C++中所拥有的。顺便问一下,你为什么要这么做?是否认为继承不是STL的一个关键设计元素?@n.m.我明白了。这样做的方法是使用new创建一个对象,然后在我不再需要它时将其删除?我记得读过这样的书,智能指针在这种情况下非常有用,但我不知道如何使用它们。至于你的问题,我不知道,但我认为我不知道甚至可以理解这个问题:o我对模板也很陌生,所以我不知道。您可以尝试返回
std::shared_ptr
返回
std::shared_ptr
是一个选项,但是返回类型应该是协变的。协变返回类型只适用于普通指针和引用。这有一个解决方法,但您真的这样做了吗在学习继承的基础知识之前,需要了解变通方法吗?这个问题的答案是因为继承在这种情况下不起作用(您现在看到了其中一个原因)@n.m.哦,我明白了。不幸的是,这是一项任务,这是我应该做的。我想我只是玩玩它,看看它是怎么做的。谢谢!谢谢!这似乎现在起作用了。不幸的是,我不能以任何其他方式使它起作用。它确实起作用,但请不要让这成为你的标准风格。始终记住这一点继承自然会导致使用指针来处理子类型。这就是原理:能够使用基类指针来处理派生类(这就是为什么首先要声明方法
virtual
)。将其设为静态局部是一个非常糟糕的主意。
main.cpp:88:24:   required from here
main.cpp:50:24: error: invalid covariant return type for 'Vect_fixe<elem, taille> Vect_fixe<elem, taille>::operator+(const elem&) [with elem = int; long unsigned int taille = 35ul]'
 Vect_fixe<elem,taille> Vect_fixe<elem, taille>::operator+(const elem& operand)
                        ^
In file included from main.cpp:9:0:
Vect.hpp:25:22: error:   overriding 'Vect<elem> Vect<elem>::operator+(const elem&) [with elem = int]'
         virtual Vect operator+(const elem&);
                      ^
main.cpp:62:24: error: invalid covariant return type for 'Vect_fixe<elem, taille> Vect_fixe<elem, taille>::operator-(const elem&) [with elem = int; long unsigned int taille = 35ul]'
 Vect_fixe<elem,taille> Vect_fixe<elem, taille>::operator-(const elem& operand)
                        ^
In file included from main.cpp:9:0:
Vect.hpp:26:22: error:   overriding 'Vect<elem> Vect<elem>::operator-(const elem&) [with elem = int]'
         virtual Vect operator-(const elem&);
int& returnByReference()
{
     static int x = 5; // static ensures x doesn't go out of scope when we return it by reference
     return x;
}

int value = returnByReference(); // case A -- ok, treated as return by value
const int &cref = returnByValue(); // case C -- ok, the lifetime of return value is extended to the lifetime of cref