我一直在环顾四周,并没有想出任何有形的解决方案。听起来它正在寻找一个默认的构造函数而不是一个默认的构造函数,但我在下面有一个。将它作为第一个列出的构造函数移动并没有改变错误消息,所以我错了。这是完整的错误消息(使用jGRASP):
In file included from intset.h:47:0,
from IntSet.cpp:1:
IntSet.cpp:12:11: error: expected unqualified-id before 'int'
IntSet(int a, int b, int c, int d, int e) {
^
IntSet.cpp:12:11: error: expected ')' before 'int'
这是IntSet.cpp代码:
#include "intset.h"
//#include <algorithm>
//#include <iostream>
int size;
const int MAXSIZE = 25000;
bool set[MAXSIZE];
const int SENTINEL = -1;
//Constructors
IntSet(int a, int b, int c, int d, int e) {
size = a;
if(b > size) {
size = b;
}
if(c > size) {
size = c;
}
if(d > size) {
size = d;
}
if(e > size) {
size = e;
}
set = new bool[size];
for(int i = 0; i <= size; i++) {
if(i == a || i == b || i == c || i == d || i == e) {
insert(i);
} else {
remove(i);
}
}
}
IntSet(int a, int b, int c, int d) {
IntSet(a, b, c, d, -1);
}
IntSet(int a, int b, int c) {
IntSet(a, b, c, -1, -1);
}
IntSet(int a, int b) {
IntSet(a, b, -1, -1, -1);
}
IntSet(int a) {
IntSet(a, -1, -1, -1, -1);
}
//Copy constructor
IntSet(const IntSet& x) {
size = x.size;
for (int i = 0; i <= x.size; i++ ) {
set[i] = x.set[i];
}
}
//Destructor
~IntSet()
{
//for(int i = this.length(); i >= 0; i--) {
// this[i]
//}
}
////////////////////////
bool insert(int a) {
if(a <= size && a >= 0) {
set[a] = true;
return true;
}
else if(a >= 0) {
//removed "new" from line below
IntSet temp = IntSet(a);
&this += temp;
set[a] = true;
return true;
}
return false;
}
bool remove (int a) {
if (isInSet(a)) {
set[a] = false;
return true;
}
return false;
}
bool isEmpty() {
bool retVal = true;
for (int i = 0; i <= size; i++) {
if (set[i] == true) {
retVal = false;
}
}
return retVal;
}
bool isInSet (int a) {
if (set[a]){
return true;
}
return false;
}
/////////////////////////////////////////////
IntSet operator + (IntSet a) {
IntSet c = IntSet(max(size, a.size));
for (int i = 0; i <= c.size; i++) {
if (set[i] || a.set[i]){
c.set[i] = true;
}
else {
c.set[i] = false;
}
}
return c;
}
IntSet operator * (IntSet a) {
IntSet c = IntSet(max(size, a.size));
for (int i = 0; i <= c.size; i++) {
if (set[i] && a.set[i]) {
c.set[i] = true;
}
else {
c.set[i] = false;
}
}
return c;
}
IntSet operator - (IntSet a) {
IntSet c = IntSet();
c.size = 0;
for (int i = 0; i <= size; i++) {
if (set[i] && !a.set[i]) {
c.set[i] = true;
}
else {
c.set[i] = false;
}
c.size++;
}
return c;
}
IntSet operator = (const IntSet a) {
return IntSet(a);
}
IntSet operator += (IntSet a) {
return IntSet(operator+(a));
}
IntSet operator *= (IntSet a) {
return IntSet(operator * (a));
}
IntSet operator -= (IntSet a) {
return IntSet(operator - (a));
}
IntSet operator == (const IntSet a) const{
for(int i = 0; i < size; i++) {
if(set[i] != a.set[i]) {
return false;
}
}
return true;
}
IntSet operator != (IntSet a) {
for(int i = 0; i < size; i++) {
if(set[i] != a.set[i]) {
return true;
}
}
return false;
}
IntSet operator << (IntSet a) {
cout << "{";
for(int i = 0; i < size; i++) {
if(set[i]) {
cout << " " << i;
}
}
cout << "}";
}
IntSet operator >> (IntSet a) {
int index;
while(cin >> index && index != SENTINEL) {
insert(index);
}
}
这是附加的intset.h代码:
#ifndef INTSET_H
#define INTSET_H
#include <iostream>
#include <algorithm>
using namespace std;
class IntSet {
public:
//Constructors
IntSet();
IntSet(int);
IntSet(int, int);
IntSet(int, int, int);
IntSet(int, int, int, int);
IntSet(int, int, int, int, int);
IntSet(const IntSet&); // M: Added the &; must be a pointer or reference
~IntSet();
//Overloaded Operators M: Added 'IntSet' in front of the word 'operator.'
// It was required syntax.
IntSet operator+(IntSet);
IntSet operator*(IntSet);
IntSet operator-(IntSet);
IntSet operator=(IntSet);
IntSet operator+=(IntSet);
IntSet operator*=(IntSet);
IntSet operator-=(IntSet);
IntSet operator==(IntSet);
IntSet operator!=(IntSet);
IntSet operator<<(IntSet);
IntSet operator>>(IntSet);
//Functions
bool insert(int);
bool remove(int);
bool isEmpty();
bool isInSet(int);
private:
const int MAXSIZE;
int size;
bool set[];
const int SENTINEL;
};
#include "IntSet.cpp"
#endif
我对头文件没有多少经验,所以如果我格式化错误,我不会感到惊讶,但是我正在查看教授提供的大量其他样本,并且没有#39我的任何不寻常之处。我想也许它与.h文件中列出的顺序有关,并且我没有遵循.cpp中相同的顺序,但是当我以相同的顺序列出所有内容时没有任何改变。
答案 0 :(得分:2)
您的代码有很多问题。我们将不得不在标题和实现之间跳过一点。准备好了吗?
在标题中,您可以执行以下操作:
class IntSet {
/* stuff */
private:
bool set[];
};
首先,名称set
是一个糟糕的选择:它是namespace
std
w中要通过using namespace std
进入的导入的类的名称你的头文件。这可能会让人感到困惑。
更重要的是,语法bool set[]
在此上下文中不正确。即使你的编译器允许它,它也是一个扩展。谁知道它的作用以及它在其他编译器上的表现如何?避免它。
如果要声明数组,请声明一个数组。如果要声明指针,请声明指针。请记住:数组不是指针。
不幸的是你没有,因为稍后在你的代码中你会这样做:
set = new bool[size];
这应该做什么? set
不是指针,它是某种数组,并且您不能指定指向数组的指针。
现在,我们遇到第二个问题:在头文件中为类声明一些成员变量:
class IntSet {
/* some stuff here */
private:
const int MAXSIZE;
int size;
bool set[];
const int SENTINEL;
};
然后在您的实现中,您将以下代码浮动在顶部:
int size;
const int MAXSIZE = 25000;
bool set[MAXSIZE];
const int SENTINEL = -1;
我认为这不符合您的想法。看来你的意图是初始化那些变量,但事实并非如此。请记住,这些变量仅作为属于特定类的实例的成员变量存在,并且它们不是“独立的”。那么这里发生了什么?
好吧,这会再次声明所有这些变量,因此你有一个名为MAXSIZE
,size
,set
和SENTINEL
的变量,它们在任何地方都是有效的 >在该翻译单元(即.cpp文件)中,独立于类中的成员变量。
当然,这意味着没有初始化具有这些名称的成员变量(除了你分配指针的set
,我们已经知道这是错误的)。这将导致您的代码显示未定义的行为。毕竟,未初始化变量的值可以是任何值。
如果您的意图是初始化类成员,那么您应该删除该代码并在构造函数中初始化这些变量:
IntSet::IntSet(int a, int b, int c, int d, int e)
: size(a), MAXSIZE(25000), SENTINEL(-1)
{
/* whatever*/
}
顺便提一下,请注意我如何在构造函数名称前面使用IntSet::
?这称为范围解析运算符。请记住,没有名为IntSet
的构造函数。构造函数属于一个名为IntSet
的类,在该类之外,它的正确名称是IntSet::IntSet
。一个小例子可能会有所帮助:
class Test
{
int Length;
public:
/* notice how inside the class, you only need Test
* when providing a body for the constructor. This
* makes sense. You know which class you inside of.
*/
Test()
: Length(0)
{
}
Test(int len);
};
/* Now we are outside the class. We need to help
* the compiler out and tell it what class the
* function belongs to.
*/
Test::Test(int len)
: Length(len)
{
}
与您正在使用的名称有关的切线点。什么是a
?为什么使用a
初始化名为size
的内容?您应该选择有意义的变量名称来帮助记录代码,这样当您必须阅读它时,您的头部不会爆炸。
另一个切入点是,如果要在类的所有实例之间共享MAXSIZE
和SENTINEL
之类的变量,那么为了将来参考,您应该考虑将它们{{1}班级成员。
最后,您在头文件中有这段代码
static
这几乎可以肯定是不正确的。你应该从不这样做(可能有些人认为有异常,但此刻并没有学习坏习惯。当你足够了解这个合法的时候,你就会知道确定这是否是正确的做法。)
更糟糕的是您的实施文件包含:
#include "IntSet.cpp"
考虑一下你在这里做了什么:当编译器正在处理文件#include "IntSet.h"
时,你要告诉他们也处理文件IntSet.h
。文件IntSet.cpp
告诉编译器处理文件IntSet.cpp
。这告诉编译器处理文件IntSet.h
。依此类推。
一般来说,实现文件(.cpp)将包含头文件。头文件只包含其他头文件。
还有一些其他问题,但您应该解决所有这些问题,然后,如果您仍然遇到问题,请发布一个新问题,我们可以从那里开始。
祝你好运!答案 1 :(得分:1)
在定义成员函数之前,您需要输入类的名称和::
。
IntSet::IntSet(int a, int b, int c, int d, int e) {
//^^^^^^^^
//here
对其他构造函数,运算符和方法执行相同的操作。