【问题标题】:how to use std in code without including "using namespace std"?如何在代码中使用标准而不包括“使用命名空间标准”?
【发布时间】:2019-06-19 06:56:22
【问题描述】:

在这个运算符重载代码中,我不想写“使用命名空间 std”,而是想在需要的地方包含“std::”。

在 cout 和 cin 之后添加“std::”后,我仍然会收到错误,包括“std::”。

#include<iostream>
//using namespace std;
class Complex
{
private:
  int real, imag;
public:
  Complex(int r = 0, int i = 0) : real(r), imag(i) {}

  friend ostream & operator << (ostream &, const Complex &);
  friend istream & operator >> (istream &, Complex &);
};

ostream & operator << (ostream &out, Complex &obj)
{
  out<<obj.real<<" "<<obj.imag;
  return out;
}
istream & operator >> (istream &in, const Complex &obj)
{
  in>>obj.real>>obj.imag;
  return in;
}

int main()
{
  Complex obj;
  std::cin>>obj;
  std::cout<<obj;
  return 0;
}

它应该使用 istream 运算符输入两个数字,并使用 ostream 运算符输出两个数字。

【问题讨论】:

  • 您遇到什么错误?
  • ostreamistream 来自哪个命名空间?

标签: c++ operator-overloading std


【解决方案1】:

std:: 添加到ostreamistream

它们来自标头&lt;istream&gt;&lt;ostream&gt;,并在&lt;iosfwd&gt; 中定义

#include<iostream>
//using namespace std;
class Complex
{
private:
    int real, imag;
public:

    Complex(int r = 0, int i = 0) : real(r), imag(i) {}

    friend std::ostream& operator<<(std::ostream& out, const Complex& obj);
    friend std::istream& operator>>(std::istream& in, Complex& obj);
};

std::ostream& operator<<(std::ostream &out, const Complex &obj)
{
    out << obj.real << " " << obj.imag;
    return out;
}
std::istream& operator>>(std::istream &in, Complex &obj)
{
    in >> obj.real >> obj.imag;
    return in;
}

int main()
{
    Complex obj;
    std::cin >> obj;
    std::cout << obj;
    return 0;
}

(与std:: 问题无关) 您还可以使用 get/set 成员函数在没有 friend 声明的情况下访问类外部的私有变量。感谢@aschepler 指出我在可访问性方面的错误。

#include<iostream>
class Complex
{
private:
    int real, imag;
public:
    int get_real() const {
        return real;
    }
    void set_real(int real) {
        this->real = real;
    }
    int get_imag() const {
        return imag;
    }
    void set_imag(int imag) {
        this->imag = imag;
    }

    Complex(int r = 0, int i = 0) : real(r), imag(i) {}

};

std::ostream& operator<<(std::ostream &out, const Complex &obj)
{
    out << obj.get_real() << " " << obj.get_real();
    return out;
}
std::istream& operator>>(std::istream &in, Complex &obj)
{
    int real, imag;
    in >> real >> imag;
    obj.set_real(real);
    obj.set_imag(imag);
    return in;
}

int main()
{
    Complex obj;
    std::cin >> obj;
    std::cout << obj;
    return 0;
}

【讨论】:

  • 据我所知,STL 没有使用命名空间。
  • 但是当我使用“命名空间标准”时它正在工作,为什么现在我必须编写一个 get_real() 和 get_imag() 函数?你能告诉我更多关于它的信息吗?
  • friend 声明允许访问私有成员。这些函数可能适用于想要获取复数的实部或虚部的其他代码,但在所示程序中它们不是必需的。
  • @AdityaIshan 我把修改后的代码贴出来了,看看吧。
  • @AdityaIshan 注意 aschepler 的推荐。这个回答有点误导,其实严格来说是错误的,可以在好友中访问私人会员
【解决方案2】:

这只是一个命名空间污染问题。它的重要性可能因用途而异。

当您只是进行原型设计时,using namespace std; 很好,包括无用的标头以防万一您需要一些东西。当您想要一个将被广泛审查的超级安全代码时,您希望防止名称冲突和命名空间污染,因此您只在当前命名空间中包含所需的内容,并为很少使用的标识符提供明确的命名空间。

以下更多是我自己的观点(或者更准确地说是我习惯的工作方式):

  • 当一个符号很少使用时,我给它明确的命名空间(例如:std::cout &lt;&lt; i;
  • 当某个符号在编译单元中被大量使用时,我会专门导入该符号(例如:using std::cout; ... cout &lt;&lt; i; ... cout &lt;&lt; j; ...

【讨论】:

    【解决方案3】:

    你最喜欢的标准库参考告诉你东西在什么命名空间中。在像这样的小程序中,你可以简单地依次查找每一个。

    提示:他们都在std

    所以这包括std::ostreamstd::istream

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      • 2023-03-31
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 2013-09-25
      相关资源
      最近更新 更多