尝试重载“+”运算符时收到错误消息说我的 class 没有命名类型
Getting error message saying my class does not name a type when trying to overload the "+" operator
当我为重载运算符 + 的友元函数编写定义时,给我错误消息的部分在实现文件中。它说统计学家没有命名类型。但它是一个友元函数,并且写在包含 header 的实现文件中,所以我不确定为什么它不识别这个。我还意识到我拼错了文件名的统计员,但不知道如何轻松地重命名代码块中的文件。
//header file
#ifndef STATISTICIAN_H
#define STATISTICIAN_H
namespace GREGORY_STOCKER_STATICTICIAN{
class Statistician{
public:
Statistician();
void next_number(double);
void erase_sequence();
int get_length() const {return length_sequence;}
double get_sum() const{return sum;}
double get_mean() const;
double get_largest() const;
double get_smallest() const;
double get_last() const;
friend Statistician operator + (const Statistician &,const Statistician &);
private:
int length_sequence;
double sum;
double smallest;
double largest;
double last;
};
#endif
}
//implementation file
using namespace std;
#include "Statictician.h"
#include <iostream>
#include <cassert>
namespace GREGORY_STOCKER_STATICTICIAN{
Statistician :: Statistician()
{
length_sequence = 0;
sum = 0;
smallest = 0;
largest = 0;
last = 0;
}
void Statistician :: next_number(double num)
{
length_sequence += 1;
sum += num;
if(length_sequence == 1)
{
smallest = num;
largest = num;
}
if (num < smallest)
smallest = num;
if (num > largest)
largest = num;
last = num;
}
void Statistician :: erase_sequence()
{
length_sequence = 0;
sum = 0;
smallest =0;
largest = 0;
last = 0;
}
double Statistician :: get_mean () const
{
assert(length_sequence > 0);
return sum / 2;
}
double Statistician :: get_largest() const
{
assert(length_sequence > 0);
return largest;
}
double Statistician :: get_smallest() const
{
assert(length_sequence > 0);
return smallest;
}
double Statistician :: get_last() const
{
assert(length_sequence > 0);
return last;
}
}
//the part that is tripping the error message
Statistician operator +(const Statistician &s1,const Statistician &s2)
{
Statistician s3;
s3.sum = (s1.sum + s2.sum);
s3.sequence_length = (s1.sequence_length + s2.sequence_length;
if(s1. largest > s2.largest)
s3.largest = s1.largest;
else
s3.smallest = s2.smallest;
if(s1. smallest < s2.smallest)
s3.smallest = s1.smallest;
else
s3.smallest = s2.smallest;
s3.last = s2.last;
return s3;
}
你要写Statistician
class的全名,像这样:
GREGORY_STOCKER_STATICTICIAN::Statistician operator +(const
GREGORY_STOCKER_STATICTICIAN::Statistician &s1,const
GREGORY_STOCKER_STATICTICIAN::Statistician &s2)
{
//....
}
另外,你不应该有这么长的命名空间名称,因为它真的很冗长(拼写错误容易出错),并且它鼓励 using
语句,鼓励基于命名冲突的错误。 2 代码的 using 语句如下所示:
using GREGORY_STOCKER_STATICTICIAN::Statistician;
哪个比备选方案更好:
using GREGORY_STOCKER_STATICTICIAN;
此外,虽然你没有提到这个错误,但你的 if... else
块需要大括号,如下所示:
if(s1. largest > s2.largest)
s3.largest = s1.largest;
else
{
s3.smallest = s2.smallest;
if(s1. smallest < s2.smallest)
s3.smallest = s1.smallest;
else
s3.smallest = s2.smallest;
}
在您之前的代码中,此代码将在块外进行计算,我认为您不希望这样,即使在这里没有任何区别。作为建议,为了可维护性,始终放置 if...else
块的大括号。
此外,由于您将 operator+
设为友元函数,因此它仅限于命名空间内的最小块范围。使 operator+
成为一个真正的成员函数,而不是友元函数,所以它看起来像这样:
Statistician operator+(const s1& other)
{
Statistician s3;
s3.sum = (s1.sum + this->sum);
s3.sequence_length = (s1.sequence_length + this->sequence_length;
if(s1.largest > largest)
s3.largest = s1.largest;
else
s3.smallest = this->smallest;
if(s1.smallest < this->smallest)
s3.smallest = s1.smallest;
else
s3.smallest = this->smallest;
s3.last = s2.last;
return s3;
}
此外,不需要显式使用 this->
,我只是想证明变量是从当前对象中获取的。
class 中的 friend
声明在最小的封闭名称空间中声明函数。所以你的 friend
声明实际上声明了和朋友 GREGORY_STOCKER_STATICTICIAN::operator +
。它既没有声明也没有朋友 ::operator +
.
但是您的代码试图在命名空间之外实现 ::operator +
。这产生了一个完全不同的功能:它不会被任何试图将两个 Statisticians 加在一起的代码找到,因为该代码只能找到命名空间版本。此外,它甚至无法编译(因为您在 Arnav Borborah 的回答下发布了错误消息):因为 ::operator +
不是 friend
,它无法访问私有成员。
所以最简单的解决方案实际上是将 operator+
定义放在命名空间中,以便它与声明相匹配:
namespace GREGORY_STOCKER_STATICTICIAN
{
Statistician operator +(const Statistician &s1,const Statistician &s2)
{
// ...
}
}
现在您也不需要符合条件 Statistician
。
当我为重载运算符 + 的友元函数编写定义时,给我错误消息的部分在实现文件中。它说统计学家没有命名类型。但它是一个友元函数,并且写在包含 header 的实现文件中,所以我不确定为什么它不识别这个。我还意识到我拼错了文件名的统计员,但不知道如何轻松地重命名代码块中的文件。
//header file
#ifndef STATISTICIAN_H
#define STATISTICIAN_H
namespace GREGORY_STOCKER_STATICTICIAN{
class Statistician{
public:
Statistician();
void next_number(double);
void erase_sequence();
int get_length() const {return length_sequence;}
double get_sum() const{return sum;}
double get_mean() const;
double get_largest() const;
double get_smallest() const;
double get_last() const;
friend Statistician operator + (const Statistician &,const Statistician &);
private:
int length_sequence;
double sum;
double smallest;
double largest;
double last;
};
#endif
}
//implementation file
using namespace std;
#include "Statictician.h"
#include <iostream>
#include <cassert>
namespace GREGORY_STOCKER_STATICTICIAN{
Statistician :: Statistician()
{
length_sequence = 0;
sum = 0;
smallest = 0;
largest = 0;
last = 0;
}
void Statistician :: next_number(double num)
{
length_sequence += 1;
sum += num;
if(length_sequence == 1)
{
smallest = num;
largest = num;
}
if (num < smallest)
smallest = num;
if (num > largest)
largest = num;
last = num;
}
void Statistician :: erase_sequence()
{
length_sequence = 0;
sum = 0;
smallest =0;
largest = 0;
last = 0;
}
double Statistician :: get_mean () const
{
assert(length_sequence > 0);
return sum / 2;
}
double Statistician :: get_largest() const
{
assert(length_sequence > 0);
return largest;
}
double Statistician :: get_smallest() const
{
assert(length_sequence > 0);
return smallest;
}
double Statistician :: get_last() const
{
assert(length_sequence > 0);
return last;
}
}
//the part that is tripping the error message
Statistician operator +(const Statistician &s1,const Statistician &s2)
{
Statistician s3;
s3.sum = (s1.sum + s2.sum);
s3.sequence_length = (s1.sequence_length + s2.sequence_length;
if(s1. largest > s2.largest)
s3.largest = s1.largest;
else
s3.smallest = s2.smallest;
if(s1. smallest < s2.smallest)
s3.smallest = s1.smallest;
else
s3.smallest = s2.smallest;
s3.last = s2.last;
return s3;
}
你要写Statistician
class的全名,像这样:
GREGORY_STOCKER_STATICTICIAN::Statistician operator +(const
GREGORY_STOCKER_STATICTICIAN::Statistician &s1,const
GREGORY_STOCKER_STATICTICIAN::Statistician &s2)
{
//....
}
另外,你不应该有这么长的命名空间名称,因为它真的很冗长(拼写错误容易出错),并且它鼓励 using
语句,鼓励基于命名冲突的错误。 2 代码的 using 语句如下所示:
using GREGORY_STOCKER_STATICTICIAN::Statistician;
哪个比备选方案更好:
using GREGORY_STOCKER_STATICTICIAN;
此外,虽然你没有提到这个错误,但你的 if... else
块需要大括号,如下所示:
if(s1. largest > s2.largest)
s3.largest = s1.largest;
else
{
s3.smallest = s2.smallest;
if(s1. smallest < s2.smallest)
s3.smallest = s1.smallest;
else
s3.smallest = s2.smallest;
}
在您之前的代码中,此代码将在块外进行计算,我认为您不希望这样,即使在这里没有任何区别。作为建议,为了可维护性,始终放置 if...else
块的大括号。
此外,由于您将 operator+
设为友元函数,因此它仅限于命名空间内的最小块范围。使 operator+
成为一个真正的成员函数,而不是友元函数,所以它看起来像这样:
Statistician operator+(const s1& other)
{
Statistician s3;
s3.sum = (s1.sum + this->sum);
s3.sequence_length = (s1.sequence_length + this->sequence_length;
if(s1.largest > largest)
s3.largest = s1.largest;
else
s3.smallest = this->smallest;
if(s1.smallest < this->smallest)
s3.smallest = s1.smallest;
else
s3.smallest = this->smallest;
s3.last = s2.last;
return s3;
}
此外,不需要显式使用 this->
,我只是想证明变量是从当前对象中获取的。
class 中的 friend
声明在最小的封闭名称空间中声明函数。所以你的 friend
声明实际上声明了和朋友 GREGORY_STOCKER_STATICTICIAN::operator +
。它既没有声明也没有朋友 ::operator +
.
但是您的代码试图在命名空间之外实现 ::operator +
。这产生了一个完全不同的功能:它不会被任何试图将两个 Statisticians 加在一起的代码找到,因为该代码只能找到命名空间版本。此外,它甚至无法编译(因为您在 Arnav Borborah 的回答下发布了错误消息):因为 ::operator +
不是 friend
,它无法访问私有成员。
所以最简单的解决方案实际上是将 operator+
定义放在命名空间中,以便它与声明相匹配:
namespace GREGORY_STOCKER_STATICTICIAN
{
Statistician operator +(const Statistician &s1,const Statistician &s2)
{
// ...
}
}
现在您也不需要符合条件 Statistician
。