提问人:Inversus 提问时间:7/22/2020 最后编辑:eyllanescInversus 更新时间:7/22/2020 访问量:66
构造函数和赋值运算符行为
Constructors and assignment operators behavior
问:
我已经将我的代码带入了工作形式,但还剩下几个问题。 所以代码(这个想法是在数组中可以同时存储一些数据和数据的子数组):
#include <iostream>
using namespace std;
template <typename T>
class Array {
public:
Array () {;}
Array(T const &a) {*this = a;}
Array(Array const &a) {Resize(SZ+1); M[SZ-1] = a;}
T& operator [] (int i) const {return M[i % SZ];}
operator T& () {return M[IX % SZ];}
Array& operator = (T const &a) {
Resize(SZ+1);
M[SZ-1] = a;
return *this;
}
Array& operator = (Array const &a)
{
Resize(a.SZ);
if (M != nullptr) {
for (int i = 0; i < SZ; i++) M[i] = a[i];
}
return *this;
}
Array<T>& operator = (Array * const p)
{
Resize(SZ+1);
M[SZ-1] = p;
return *this;
}
friend ostream& operator<<(ostream& os, const Array<T> &a)
{
for (int i = 0; i < a.SZ; i++) os << a.M[i] << ",";
return os;
}
protected:
T *M = nullptr;
int SZ = 0, IX = 0;
private:
Array& Resize(int s)
{
if (s != 0) {
int S = SZ;
if (S > s) S = s;
T *A = new T[s];
if (A != nullptr) {
int i;
for (i = 0; i < S; i++) A[i] = M[i];
delete M;
M = A;
SZ = s;
}
} else {
delete M;
SZ = 0;
}
return *this;
}
};
struct S {
enum class TP {
INT,
ARR
} type;
int data = 0;
Array<S> *ptr = nullptr;
S() {;}
S(int d) {type = TP::INT; data = d;}
S(float d) {type = TP::INT; data = d;}
S(Array<S>* p) {type = TP::INT; ptr = p;}
int operator = (int d) {type = TP::INT; return data = d;}
int operator = (float d) {type = TP::INT; return data = d;}
Array<S>* operator = (Array<S>* p) {type = TP::ARR; return ptr = p;}
friend ostream& operator << (ostream& os, const S &s)
{
switch (s.type) {
case TP::INT:
os << s.data;
break;
case TP::ARR:
os << "[" << *s.ptr << "]";
break;
default:
os << "ERROR";
}
return os;
}
};
int main()
{
Array<S> arr0, *arr1 = new Array<S>;
arr0 = 10;
arr0 = 20;
arr0 = 30;
*arr1 = 40;
*arr1 = 50;
*arr1 = 60;
arr0 = arr1;
cout << arr0;
return 0;
}
现在我将注释掉这些行
S(int d) {type = TP::INT; data = d;}
S(float d) {type = TP::INT; data = d;}
S(Array<S>* p) {type = TP::INT; ptr = p;}
int operator = (int d) {type = TP::INT; return data = d;}
int operator = (float d) {type = TP::INT; return data = d;}
Array<S>* operator = (Array<S>* p) {type = TP::ARR; return ptr = p;}
我将按顺序取消注释它们。 起初,我收到错误消息:
main.cpp:34:错误:没有可行的重载“=” main.cpp:34:错误:'operator=' 不匹配 (操作数类型为“S” 和 'Array* const')
M[SZ-1] = p;
~~~~~~~~^~~
到目前为止,一切都很清楚。如果我取消注释该行
S(float d) {type = TP::INT; data = d;}
然后我会收到相同的消息。但是,如果我取消注释该行
S(int d) {type = TP::INT; data = d;}
我收到错误消息:
main.cpp:34: error: invalid conversion from 'Array<S>*' to 'int' [-fpermissive]
M[SZ-1] = p;
~~~~~~~~^~~
为什么编译器不尝试将 Array 转换为浮点数,而是尝试将 int 转换为 int ?
然后,我可以删除以下行:
int operator = (int d) {cout << "=int" << endl;type = TP::INT; return data = d;}
一切都会好起来的。然后我认为构造函数和运算符“=”是可以互换的,我可以删除 Array 类中的运算符“=”:
Array& operator = (T const &a) {
Resize(SZ+1);
M[SZ-1] = a;
return *this;
}
但我不能,这会导致错误!但是我可以删除 Array 类构造函数:
Array(Array const &a) {Resize(SZ+1); M[SZ-1] = a;}
这将起作用。相反,如果我删除结构构造函数但保留赋值运算符,则会出现错误。
我有一些猜测,但我很困惑。有人可以清楚地解释为什么会有这种行为吗?
对不起,如果我没有解释清楚。
答: 暂无答案
评论