我一直试图重载<< (cout)和>> (cin)运算符现在有一段时间用于一类复数,我在.h文件中给出了原型。
这是我尝试在class.cpp文件中执行此操作:
std::istream &operator>> (std::istream &in, complex& c) {
double h, j;
in >> h >> j;
c.set(h,j);
return in;
}
std::ostream &operator<<(std::ostream &out, complex c) {
out << c.getReal;
out << c.getImag;
return out;
}
这是我第一次见到std:: istream
和std:: ostream
而不是cout和cin,我不确定cout <<
和{{1}都是相关的
我尝试在main.cpp文件上测试它,但是我收到了错误
cin >>
应该将复杂的参数吸收到复杂的类参数中,并更改私有成员的值>>
和real
不确定我是否应该在这里使用我的设置功能
这是我给出的原型.h文件:
imag
有人可以告诉我如何适当地超载吗?
好的,我现在正在尝试输出a + bi:
#ifndef COMPLEX_H
#define COMPLEX_H
class complex {
public:
complex();
complex(double a);
complex(double a, double b);
complex(int a, int b);
void print() const;
void set(double a = 0, double b = 0);
void set(int a = 0, int b = 0);
double getReal() const;
double getImag() const;
void get(double&, double&) const;
complex operator+ (double& x);
complex operator+ (complex&);
complex operator+= (complex&);
complex operator+= (int&);
complex operator++ (int);
complex operator++ ();
complex operator- (double&);
complex operator- (complex&);
complex operator-= (complex&);
complex operator-= (double&);
complex operator-- (int);
complex operator-- ();
complex operator* (complex&);
complex operator* (double&);
complex operator*= (complex&);
complex operator*= (double&);
complex operator/ (complex&);
complex operator/= (complex&);
complex operator/= (double);
complex operator/ (double);
void operator= (const complex&);
bool operator== (complex&);
bool operator!=(complex &c);
friend std::istream &operator>> (std::istream &in, complex& c);
friend std::ostream &operator<<(std::ostream &out, complex c);
/*complex conj() const;
double norm() const;
double modulus() const;
*/
private:
double real;
double imag;
};
#endif // COMPLEX_H
并输入:
std::ostream& operator<< (std::ostream& out, complex const& c) {
return out << c.getReal() << "+" << c.getImag() << "i";
}
但是编译时出现以下错误:
这是我的complex.cpp文件(类复杂实现文件)的第181行,其中std::istream& operator>> (std::istream& in, complex& c) {
double h, j;
if (in >> h >> "+" >> j >> "i") {
c.set(h, j);
}
return in;
}
位于上面的函数定义中:
if (in >> h >> "+" >> j >> "i") {
以下是我的complex.h文件中第45行(注意每个错误是单独的,总共7行),其中binary '>>': no operator found which takes a right-hand operand of type 'const char [2]' (or there is no acceptable conversion)
原型所在。
friend std::istream &operator>> (std::istream &in, complex& c);
以下是我的complex.h文件的第46行
'istream':is not a member of 'std'
syntax error missing ';' before '&'
'istream':'friend' not permitted on data declarations
missing type specifier-int assumed. Note:C++ does not support default-int
unexpected token(s) preceding';'
namespace "std" has no member "istream"
namespace "std" has no member "istream"
位于
friend std::ostream &operator<<(std::ostream &out, complex c);
我注意到两者都是同一类型的错误。注意我有
'ostream': is not a member of 'std'
syntax error: missing ';' before '&'
'ostream':'friend' not permitted on data declarations
missing type specifier -int assumed.Note: C++ does not support default-int
unexpected token(s) preceding ';'
namespace "std" has no member "ostream"
namespace "std" has no member "ostream"
在complex.cpp文件和main.cpp文件
上答案 0 :(得分:6)
让我们从简单的东西开始:std::cin
是从std::istream
派生的类型的实例。同样,std::cout
是从std::ostream
派生的类型的实例。这些流类型用于为输入和输出操作符重载(并且不尝试从它们派生以改变它们的行为 - 使用{{1}完成的操作})。还有其他流类型,例如std::streambuf
/ std::ifstream
(读取/写入文件)和std::ofstream
/ std::istringstream
(读取/写入字符串)。
接下来要看的是输出操作符:对于初学者,在调用成员函数时需要括号。您还需要在两个值之间使用分隔符,否则实部和虚部可能相互融合。我可能会将操作符实现为
std::ostringstream
使用空格而不使用其他分隔符通常可能不是最理想的,但会使阅读更容易。对于复杂类的实际实现,我可以使用格式编写 real std::ostream& operator<< (std::ostream& out, complex const& value) {
return out << value.getReal() << " " << value.getImag();
}
imag +
或i
real (
imag ,
但这些内容难以解析。
在尝试读取值之后,应该从流中读取值始终。例如,代码可能如下所示:
)
除了丢失的检查外,输入函数看起来没问题,假设两个值之间用空格分隔:在尝试读取值之前,默认情况下会使用输入运算符跳过空格。如果使用某些分隔符将值格式化得更加精美,则需要单独处理这些分隔符。这样做的代码可能如下所示:
std::istream& operator>> (std::istream& in, complex& c) {
double h, j;
if (in >> h >> j) {
c.set(h, j);
}
return in;
}
这些看起来很滑稽的实体template <char C>
std::istream& skip_char(std::istream& in) {
if ((in >> std::skipws).peek() != C) {
in.setstate(std::ios_base::failbit);
}
else {
in.ignore();
}
return in;
}
std::istream& (*const open_parenthesis)(std::istream&) = &skip_char<'('>;
std::istream& (*const close_parenthesis)(std::istream&) = &skip_char<')'>;
std::istream& (*const comma)(std::istream&) = &skip_char<','>;
std::istream& operator<< (std::istream& in, complex& c) {
double real, imag;
if (in >> open_parenthesis >> real >> comma >> imag >> close_parenthesis) {
c.set(real, imag);
}
return in;
}
,open_parenthesis
和close_parenthesis
是初始化为指向函数模板comma
实例的函数指针。他们有一个特定的签名,使他们有资格成为操纵者。当&#34;读入&#34;一个操纵器,相应的函数被调用它们是&#34;读&#34;从。也就是说,例如skip_char
会产生一个呼叫std::cin >> comma
,这实际上是对comma(std::cin)
的呼叫。但是,我想对于这项任务,全面的方法有点矫枉过正。