注意:答案是按照特定的顺序给出的,但由于许多用户根据投票而不是给出的时间对答案进行排序,因此这里是答案的索引,它们是最有意义的顺序:
(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)
我觉得我对friend关键字的理解有点漏洞.
我有一节课presentation.我在我的代码中使用它来获取两个变量,present1并且present2我将其与之比较==:
if(present1==present2)
Run Code Online (Sandbox Code Playgroud)
这是我如何定义运算符==(in class presentation):
bool operator==(const presentation& p) const;
Run Code Online (Sandbox Code Playgroud)
但是,我被告知friend在课堂外使用和定义它更好:
friend bool operator==(presentation&, presentation&);
Run Code Online (Sandbox Code Playgroud)
为什么?这两者有什么区别?
我想实现一个运算符<< for streaming my class(比如说它的名字Paragraph).类Paragraph有一些私有数据,因此我希望(独立)运算符<<函数成为朋友.所以,我按照建议做,例如,在这里.friend声明,实施operator<<和一切都很好.
但是现在我想将Paragraph放在命名空间中namespace foo.它不再有效!如果我写:
namespace foo {
class Paragraph {
public:
explicit Paragraph(std::string const& init) :m_para(init) {}
std::string const& to_str() const { return m_para; }
private:
friend std::ostream & operator<<(std::ostream &os, const Paragraph& p);
std::string m_para;
};
} // namespace foo
Run Code Online (Sandbox Code Playgroud)
编译器告诉我,我已成为朋友foo::operator<<,而不是::operator<<.好,可以.所以,我用以下内容替换了朋友行:
friend std::ostream & ::operator<<(std::ostream &os, const Paragraph& p);
Run Code Online (Sandbox Code Playgroud)
但我再次收到错误(来自GCC 5.4.0),告诉我::operator<<尚未宣布.好的,我们先声明吧.这有用吗?:
namespace foo {
std::ostream & ::operator<<(std::ostream &os, …Run Code Online (Sandbox Code Playgroud) 有人可以向我解释来自 g++ 的警告吗?
鉴于以下代码
#include <iostream>
namespace foo
{
struct bar
{ friend std::ostream & operator<< (std::ostream &, bar const &); };
}
std::ostream & foo::operator<< (std::ostream & o, foo::bar const &)
{ return o; }
int main ()
{
foo::bar fb;
std::cout << fb;
}
Run Code Online (Sandbox Code Playgroud)
我得到(来自 g++ (6.3.0) 但不是来自 clang++ (3.8.1) 而不是(感谢 Robert.M)来自 Visual Studio(2017 社区))这个警告
tmp_002-11,14,gcc,clang.cpp:10:16: warning: ‘std::ostream& foo::operator<<(std::ostream&, const foo::bar&)’ has not been declared within foo
std::ostream & foo::operator<< (std::ostream & o, foo::bar const &)
^~~
tmp_002-11,14,gcc,clang.cpp:7:29: …Run Code Online (Sandbox Code Playgroud) 当您打算打印对象时,将使用友元运算符<<.我们可以使用成员函数运算符<<?
class A {
public:
void operator<<(ostream& i) { i<<"Member function";}
friend ostream& operator<<(ostream& i, A& a) { i<<"operator<<"; return i;}
};
int main () {
A a;
A b;
A c;
cout<<a<<b<<c<<endl;
a<<cout;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有一点是朋友功能使我们能够像这样使用它
cout<<a<<b<<c
Run Code Online (Sandbox Code Playgroud)
还有什么原因?
我已经通读了运算符<<被实现为朋友还是作为成员函数?和C++中的重载插入运算符看起来像是类似的问题,但没有解决我自己的问题.
我的头文件:
using namespace std;
class Animal {
private:
friend ostream & operator<< (ostream & o, Dog & d);
int number;
public:
Animal(int i);
int getnumber();
};
ostream & operator<< (ostream & o, Dog & d);
Run Code Online (Sandbox Code Playgroud)
我的cpp:
using namespace std;
int Animal::getnumber(){
return number;
}
ostream & Animal::operator<< (ostream & o, Dog & d){
//...
}
Animal::Animal(int i) : number(i){}
Run Code Online (Sandbox Code Playgroud)
实现很简单,但我收到错误:在cpp中 - 错误:类"Animal"类没有成员"operator <<".我真的没有得到它,因为我已经在Animal中将插入操作符声明为朋友,为什么我仍然会收到此错误?(把ostream放在公共场合并没有帮助)
这是我的班级:
#ifndef CLOCK_H
#define CLOCK_H
using namespace std;
class Clock
{
//Member Variables
private: int hours, minutes;
void fixTime( );
public:
//Getter & settor methods.
void setHours(int hrs);
int getHours() const;
void setMinutes(int mins);
int getMinutes() const;
//Constructors
Clock();
Clock(int);
Clock(int, int);
//Copy Constructor
Clock(const Clock &obj);
//Overloaded operator functions
void operator+(const Clock &hours);
void operator+(int mins);
void operator-(const Clock &hours);
void operator-(int minutes1);
ostream &operator<<(ostream &out, Clock &clockObj); //This however is my problem where i get the error C2804. …Run Code Online (Sandbox Code Playgroud) I have some structs as:
struct dHeader
{
uint8_t blockID;
uint32_t blockLen;
uint32_t bodyNum;
};
struct dBody
{
char namestr[10];
uint8_t blk_version;
uint32_t reserved1;
}
Run Code Online (Sandbox Code Playgroud)
and I have a stringstream as:
std::stringstream Buffer(std::iostream::in | std::iostream::out);
Run Code Online (Sandbox Code Playgroud)
I want to write a dHdr and multiple dBody structs into Buffer with
Buffer << Hdr1;
Buffer << Body1;
Buffer << Body1;
Run Code Online (Sandbox Code Playgroud)
I get the error:
error: no match for 'operator<<' in 'Buffer << Hdr1'
If I try it with:
Buffer.write(reinterpret_cast<char*>(&Hdr1), sizeof(dbHdr1));
Buffer.write(reinterpret_cast<char*>(&Body1), sizeof(Body1));
Buffer.write(reinterpret_cast<char*>(&Body2), …Run Code Online (Sandbox Code Playgroud) 我无法弄清楚为什么以下代码无法编译.语法与我的其他运算符重载相同.是否存在限制,必须对"超载"进行限制?如果是这样,为什么?谢谢你的帮助.
这不起作用 -
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
class Test
{
public:
explicit Test(int var):
m_Var(var)
{ }
std::ostream& operator<< (std::ostream& stream)
{
return stream << m_Var;
}
private:
int m_Var;
};
int _tmain(int argc, _TCHAR* argv[])
{
Test temp(5);
std::cout << temp;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这确实有效 -
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
class Test
{
public:
explicit Test(int var):
m_Var(var)
{ }
friend std::ostream& operator<< (std::ostream& stream, Test& temp);
private:
int m_Var;
}; …Run Code Online (Sandbox Code Playgroud)