分离的 cpp 上的 C++ ostream 重载

标签 c++ operator-overloading c++14 c++builder

我是 C++ 的新手,正在阅读 Stroustrup 的书,但我对类的运算符重载有疑问。我有这 3 个文件:

enter image description here

我像往常一样有两个文件,在标题中我有定义:

#ifndef EQUATIONS_H
#define EQUATIONS_H

#include<vector>

namespace equations {

 //solve second degree equation
 class eqSecDeg {

  private:
   double a;
   double b;
   double c;
   std::vector<double> solArray;
   double getDelta(double a, double b, double c);

  public:
   eqSecDeg(const double valA, const double valB, const double valC);
   double getDelta();
   std::vector<double> getSolutions();

   //thrown with the error
   class EquationError {

    private:
     char* msg;
     int error_number;

    public:
     char* getMsg() { return msg; }
     EquationError(char* a = "Error.", int err = 0) {
      msg = a;
      error_number = err;
     };

   };

   //std::ostream& operator << (const std::ostream& x, eqSecDeg& A);
   // ^ is commented but it gives the error that it should be declared with only 1 parameter (?)    

 };

}

#endif

在这里你可以看到dqsecdegree.cpp的实现:

#include<math.h>
#include "dqsecdegree.h"

namespace equations {

 double eqSecDeg::getDelta(double a, double b, double c) {
  return (b*b)-(4*a*c);
 }

 double eqSecDeg::getDelta() {
  return (b*b)-(4*a*c);
 }

 //constructor
 eqSecDeg::eqSecDeg(const double valA, const double valB, const double valC) {

  if (valA == 0) {
   throw EquationError("Parameter 'a' cannot be zero.", 1);
  }

  a = valA;
  b = valB;
  c = valC;

 }

 std::vector<double> eqSecDeg::getSolutions() {

  double delta = getDelta(a,b,c);

  if (delta >= 0) {

   //x1 real and complex
   solArray.push_back( (-b+sqrt(delta))/(2*a) );
   solArray.push_back(0);
   //x2 real and complex
   solArray.push_back( (-b-sqrt(delta))/(2*a) );
   solArray.push_back(0);

  } else {

   delta *= -1;

   //x1 real and complex
   solArray.push_back( -b/(2*a) );
   solArray.push_back( (sqrt(delta)/(2*a)) );
   //x2 real and complex
   solArray.push_back( -b/(2*a) );
   solArray.push_back( -(sqrt(delta)/(2*a)) );

  }

  return solArray;

 }

 std::ostream& eqSecDeg::operator << (std::ostream& x, eqSecDeg& A) {
  return x << "something here";
 }

}

SO 和 google 上有很多答案,但我找不到正确的答案。我试图了解如何使用运算符重载。 我想在头文件中声明运算符重载及其在 cpp 上的实现是正确的。

  • 为什么编译器告诉我参数太多?我确定(?)我需要其中的两个(ostream 和类)
  • 我知道 friend 关键字只提供对所有成员的访问权限,而不会使该方法成为类的一部分。当我使用该关键字时,编译器告诉我没有 int/double/char/whatever 的 ostream 输出的有效定义。 我应该在哪里定义运算符重载?

我无法理解我必须在哪里(以及如何)实现它。有什么建议吗?


不是很相关,但主要是做这样的事情:

//a, b, c taken from the cin istream
equations::eqSecDeg solver(a,b,c);
std::vector<double> soluzioni = solver.getSolutions();

//here I'd like to call this
std::cout << solver;

最佳答案

  1. 在 .h 文件中将函数声明为非成员函数。

    std::ostream& eqSecDeg::operator<<(std::ostream& x, eqSecDeg const& A);
    
  2. 像您一样在 .cpp 文件中实现函数。更新它以使用 const& 而不是非常量 &

  3. 在任何你喜欢的地方使用它。

    eqSecDeg A;
    
    ...
    
    std::cout << A << std::endl;
    

关于分离的 cpp 上的 C++ ostream 重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43287596/

相关文章:

templates - 用于模板化重载的不明确运算符<<

c++ - BigInteger 类实现重载运算符 '+'

c++ - 使用继承的成员运算符而不是免费的成员运算符

c++ - 使用 std::function 和通用 lambda 的函数重载:std::string 优于 int

c++ - 如何避免 Helgrind 的误报?

c++ - 将 cv::mat 加载到更快的 rcnn blob

c++ - 如何解决C++中的异步任务错误

c++ - C++ 标准是否允许合并分配的实现?

c++ - 将文件的元素加载到 C++ 中的二维数组中

c++ - 我正在计算的序列(冰雹)在需要打印一次时打印两次