-1

我不经常涉足 C++,但我正在学习数据结构,这本书使用 C++ 作为它的语言。我目前正在设置课程。

我的问题是:

  1. Visual Studio 2012 对未知变量大喊大叫。我在我的标题中声明了变量,所以我不太确定我为什么会遇到这个问题。

  2. 我正在尝试重载加法和乘法运算符(作为非成员函数),但它仍在尝试使用它,就好像我只允许有一个重载参数一样。

这是我正在做的一些代码:

1. 不明变量

/* Quadratic.h */

#include <iostream>
using namespace std;

class Quadratic 
{
 public: 
     // constructors
     Quadratic::Quadratic()

     // accessors
     Quadratic::getA();
     Quadratic::getB();
     Quadratic::getC();

     // mutators
     Quadratic::setCoefficients(float coA, float coB, float coC);

private:
    float a, b, c, x;

};

二次方.cpp:

/* Quadratic.cpp */

#include <iostream>
#include "Quadratic.h"
using namespace std;

class Quadratic 
{

 // Default constructor
 Quadratic::Quadratic() 
 {
     a = 0;    // Visual Studio is complaining about a, b, & c
     b = 0; 
     c = 0;
 }

 /* Mutators */
 void Quadratic::setCoefficients(float coA, float coB, float coC) 
 {
     a = coA;
     b = coB;
     c = coC;
 }

 /* Accessors */
 float Quadratic::getA() const {
     return a;
 }

 float Quadratic::getB() const {
     return b;
 }

 float Quadratic::getC() const {
     return c;
 }

};

这就是第一个问题的内容。我不太确定为什么它无法找到这些变量。有人可以指出我做错了什么吗?

2.重载运算符(参数不匹配)

/* Quadratic.h */

/* Overloading Operators */
Quadratic & operator+(const Quadratic & q1, const Quadratic & q2);
Quadratic & operator*(double r, const Quadratic & q);

它只是告诉我我有太多参数。我在想它期望做类似的事情q1.operater+(q2),因为我希望能够做类似的事情q3 = q1 + q2

任何指针都可以很好地解决这些小问题。

编辑

按要求编译错误:

error C2804: binary 'operator +' has too many parameters
error C2804: binary 'operator *' has too many parameters

基本上我上面提到的,也许我并不清楚。

编辑 2

不知道为什么它被否决,但如果你要否决它,至少说明原因......如果是因为问题是新手?因为这个问题措辞或解释不当,或者只是因为你的自我太高了?当某人试图学习新事物时,无需贬低他们。

除此之外,感谢legend2kjohnstevesaldabasile抽出时间帮助我。我真的很感激。C++ 比 Java 多得多。

4

4 回答 4

5

在您的Quadratic.cpp中,您需要删除该行:

class Quadratic 
{

因为这将您的定义隐藏Quadratic在头文件中。但是,这会在您的头文件中隐藏错误。在 .h 文件中,您必须指定方法的返回类型,并且不需要使用 . 限定方法名称Quadratic。要修复运算符重载错误,请确保在头文件中的类声明之外声明它们。

class Quadratic {
     //...
     // accessors
     float getA() const;
     float getB() const;
     float getC() const;

     // mutators
     void setCoefficients(float coA, float coB, float coC);

     // rest of class definition as in question...

};   // end of class declaration

Quadratic & operator+(const Quadratic & q1, const Quadratic & q2);
Quadratic & operator*(double r, const Quadratic & q);

重载运算符可能会导致细微的错误。我强烈建议您阅读此页面以避免常见的陷阱: 运算符重载

于 2013-10-12T19:34:07.063 回答
2

按照John 的建议,将operator+andoperator*函数移到类之外。但是,您必须使这些函数成为类的朋友,因为您需要访问对象的私有变量。

此外,您已将运算符函数声明为返回引用,但对于您需要的语法q3 = q1 + q2;,您必须在构造新对象后按值返回。所以在删除当前operator+operator*功能后,你必须做

class Quadratic
{
    . . .
    friend Quadratic operator+ (const Quadratic &lhs, const Quadratic &rhs);
    friend Quadratic operator+ (double scalar, const Quadratic &rhs);
}

Quadratic operator+ (const Quadratic &lhs, const Quadratic &rhs)
{
    Quadratic result;
    result.setCoefficients(lhs.a + rhs.a, lhs.b + rhs.b, lhs.c + rhs.c);
    return result;
}

如果你像这样制作你的构造函数

Quadratic::Quadratic(float coA = 0.f, float coB = 0.f, float coC = 0.f) :
    a(coA),
    b(coB),
    c(coC),
    x()
{
}

即使用默认参数,您可以在一行中编写运算符函数:

Quadratic operator+ (const Quadratic &lhs, const Quadratic &rhs)
{
    return Quadratic(lhs.a + rhs.a, lhs.b + rhs.b, lhs.c + rhs.c);
}

这将有助于避免复制的返回值优化 (RVO) 。同样在构造函数中使用初始化列表比成员赋值要好

于 2013-10-12T20:06:17.917 回答
2

看起来你正在重新声明你的整个班级。在 C++ 中,您说一次声明接口的类(通常在 h 文件中),然后开始定义方法(通常在 cpp 文件中)。通过class在这两个文件中说您是在重新声明类而不是定义实现。

此外,您不需要Quadratic::在类声明中说明,因为class关键字使您在其中声明的任何内容都在类范围内定义。相反,当您编写实现时,您确实需要预先添加Quadratic::,因为您不再位于类范围内。

最后,你也不需要“使用”namespace std两次。放在类声明之前的h文件中就够了;它也可以从 cpp 文件中的类实现访问,因为 cpp 文件包含 h 文件。

于 2013-10-12T19:54:06.093 回答
1

通常的做法是在构造函数的主体之前初始化成员变量(即字段):

Quadratic::Quadratic() : a(0), b(0), c(0), x(0) {};

然后我相信编译器会将这些字段视为已初始化。(至少 GCC 是这样)。

您可以在类中声明一些运算符,请参见此处

class Quadratic {
  Quadratic & operator += (const Quadratic&right);

您可以在课堂之外声明它,例如

  Quadratic operator + (const Quadratic& left, const Quadratic& right);

正如其他人告诉您的那样,您可能想要返回一个值,而不是引用。

请注意,这*this是您通常应该返回的左操作数。

顺便说一句,请显示您收到的确切错误消息及其确切位置。

于 2013-10-12T19:34:40.490 回答