Class creation [Begineer in programming] - c++

It's my first code with classes. the dev c++ compiler find 4 errors so i need a help. I think there's something wrong in my concept may be
This was the Header file "complex.h"
class complex{
public:
bool ReadComplex();
private:
double real;
double imag;
};
This is the .cpp file
#include "complex.h"
#include <iostream.h>
#include <math.h>
using namespace std;
bool complex::ReadComplex()
{ cout<<"Enter the real part";
cin>>real;
cout<<"Enter the imaginary part";
cin>>imag;
return true;
}
and i got 4 errors
C:/Dev-Cpp/include/c++/3.4.2/mingw32/bits/c++config.h:57: error: expected unqualified-id before "namespace"
C:/Dev-Cpp/include/c++/3.4.2/mingw32/bits/c++config.h:57: error: expected ,' or;' before "namespace"
C:/Dev-Cpp/include/c++/3.4.2/mingw32/bits/c++config.h:61: error: expected namespace-name before ';' token
C:/Dev-Cpp/include/c++/3.4.2/mingw32/bits/c++config.h:61: error: `' is not a namespace
Thanks a lot,

class definition should end with a ;
class complex
{
// ....
} ;
//^ missing semi-colon

You forgot the semicolon at the end of the class definition:
class complex{
}; //<------- here put a semicolon

Make sure you put the class in your own named namespace, or else not say using namespace std. There's a std::complex type, and although you don't include its header, implementors are allowed to include it themselves in any of the standard headers.
End your class definition with a semicolon: class complex { /* ... */ };
Don't use <iostream.h>. Use <iostream>. Things there are in the std:: namespace, by the way.
What's <Math.h>? Is it some 3rd party library you're using that's installed outside your project tree? If it's your own code or inside your project tree then use double quotes, not angle brackets. Double quotes ask the compiler to search for the code in your tree, whereas angle brackets ask the compiler to look in system directories.
Are you sure the standard math header won't do? Take a look at the <cmath> header.
You should also
make GetReal() and GeatImag() const functions. If the Get or Set counterparts don't do anything special you should throw them away and set the member data public. This because less code is less bugs.
You should take parameters as const references whenever it makes sense. Like in complex::Add(), for example, which should be a const function too if it doesn't change the object.

Your first code with classes should be:
class complex{
};
int main()
{
return(0);
}
Seriously. Get this to work, with no compiler warnings. Then add complexity a little at a time, and never add to code that doesn't work.

Related

C++ error: expected initialiser before 'class'

When I compile the program I am working on I get:
expected initializer before 'class'
error in my Class.h file. I looked up the error message on the internet, but couldn't find the exact error, although similar errors seem to be caused by missing semicolons but I don't see why I need one. This is the code the error points to, I have no other functions or classes before it.
class Account
{
public:
double dAccountBalance;
double dAccountChange(double dChange);
};
In the Class.cpp file the double dAccountChange(double dChange) function is defined. I don't think this is where the error is coming from but this is the code;
double Account::dAccountChange(double dChange)
{
dAccountBalance += dChange;
return 0.0;
}
When I change the code in Class.h to look like this,
;
class Account
{
public:
double dAccountBalance;
double dAccountChange(double dChange);
};
it doesn't generate an error message, but I can't work out why I need the semicolon before it as the only code I have before it are the following pre-processor lines.
#ifndef CLASS_H_INCLUDED
#define CLASS_H_INCLUDED
Any ideas on why the error is generated?
Most likely, in the header file you include immediately before class.h, you'll have something like:
class xyzzy {
int plugh;
}
without the closing semi-colon. That will make your code sequence:
class xyzzy {
int plugh;
}
class Account
{
public:
double dAccountBalance;
double dAccountChange(double dChange);
};
which is clearly invalid. Inserting a semi-colon in class.h before the first line will fix it, but it's clearly the wrong place to put it (since it means every header file you include immediately after that one would need a starting semicolon - also, it's part of the definition in the first header and should be there).
Now that may not be the exact code sequence but it will be something very similar, and the underlying reason will be a missing piece of text in the previous header.
You should go back and put it in the earlier include file.
For example, consider:
include1.h:
class xyzzy {
int plugh;
}
include2.h:
class twisty {
int little_passages;
};
main.cpp:
#include "include1.h"
#include "include2.h"
int main (void) {
return 0;
}
Compiling this produces:
include2.h:3: error: multiple types in one declaration
but placing the semicolon at the end of include1.h (or start of include2.h though we've already established that's not a good idea) will fix it.
The problem is in one of the other headers, one that you #include ahead of class.h.
If you show us the top of your main cpp file, it might give a clue.

friend function issues

I'm having some difficulties with friend functions in C++, but my suspicion is that is more of a symptom of a problem I have with preprocessor directives and #include.
This is a silly example of what I was doing. Five files: bobby.h, bobby.cpp, billy.h, billy.cpp, and main.cpp. Billy has a protected function called ReceiveMoney. Bobby has a function called bank that calls Billy's ReceiveMoney. i.e. every time Bobby goes to the bank he splits the money with Billy.
billy.h
#ifndef BILLY_H
#define BILLY_H
#include "bobby.h"
class Billy
{
friend void Bobby::Bank(int, Billy &);
public:
Billy();
protected:
void ReceiveMoney(int inc);
private:
int money;
};
#endif
billy.cpp
#include "billy.h"
Billy::Billy()
{
money = 0;
}
void Billy::ReceiveMoney(int inc)
{
money+=inc;
}
bobby.h
#ifndef BOBBY_H
#define BOBBY_H
#include "billy.h"
class Bobby
{
public:
Bobby();
void Bank(int amount, Billy & b);
protected:
int money;
};
#endif
bobby.cpp
#include "bobby.h"
Bobby::Bobby()
{
money = 0;
}
void Bobby::Bank(int amount, Billy & b)
{
b.ReceiveMoney(amount/2);
}
main.cpp
#include "billy.h"
#include "bobby.h"
int main()
{
Bobby bo;
Billy bi;
bo.Bank(150, bi);
return 0;
}
I get a large number of errors, usually
error C2653: 'Bobby' : is not a class or namespace name
or
error C2653: 'Billy' : is not a class or namespace name
I'm doing this in an empty console project in VS0
You have a Circular dependency of header files.
billy.h includes bobby.h, while bobby.h includes billy.h.
Obviously, the compiler cannot make out the types due to this circular dependency.
The best solution is to rethink your design and avoid the circular dependency or
Use Forward declarations to break the circular dependency.
Just forward declare class Billy in bobby.h
//#include "billy.h" <----- You don't need this include
class Billy; <----- Just Forward Declaration should suffice
You can use a forward declaration here because, Declare functions or methods which accepts/return incomplete types, in this case Billy is an Incomplete type for the compiler.
There is a loop in your #include, you cannot do that. You must use a forward declaration of Bobby in billy.h. Such as class Bobby;. You won't be able to declare the friend function even with that.
The only real solution is to avoid the need for a friend. ReceiveMoney should be public in fact: if Bobby represents something like an account, it is logical.
The constraints on friend makes it useful only to solve inner behaviour of classes (for example with collections and nodes implementing them).
Due to circular dependency none of the classes are fully defined. hence the large number of errors. If possible change your design and inherit or include only things necessary. As mentioned by Als forward declarations can be a choice.
Circular dependencies mostly arise due to design faults.

Variable was not declared in this scope?

I'm getting this error in several methods for several variables (all of which are vectors):
error: ‘parent’ was not declared in this scope
I've tried wrapping my method implementations inside of "namespace DisjointSubsets { ... }", but that causes other problems. It seems to only do this for vectors, and I've tried adding a "#include vector" at the start of the cpp file, it didn't change anything.
Here is the header file:
#ifndef UNIVERSE
#define UNIVERSE
#include <vector>
class DisjointSubsets {
public :
DisjointSubsets ( unsigned numberElements = 5 ) ;
unsigned findDS ( unsigned ) ;
bool unionDS ( unsigned , unsigned ) ;
private :
vector<unsigned> parent ;
vector<unsigned> rank ;
unsigned size ;
} ;
#include "DisjointSubsets.cpp"
#endif
And here is an example of one of the methods I wrote in the cpp file (which has no #includes):
unsigned DisjointSubsets::findDS(unsigned index) {
return parent[index];
}
(Changed the method to be non-functional, but still illustrate the kind of line that would cause a problem. Just in case someone else working on the assignment stumbles across this.)
You must use std::vector<unsigned> instead of just vector<unsigned> to declare parent because vectoris declared in the std namespace.
Therefore you could also use using namespace std; before declaring the class.
However most people I know would discourage you from using the second form in a header file.
See the C++ FAQ for a more elaborate discussion on this topic.
vector is in the std namespace. Use std::vector or put a using namespace std; after your #includes.
You cannot include .cpp files like this and expect it to work. That code is compiled independently, as well as as a part of other translation units. When you attempt to compile, that C++ code is compiled- but you didn't include the declaration. Unless the class is a template, the .cpp should include the .h, not the other way around.

c++ headers keeping sane

The biggest problem I seem to run into when coding in c++ is the fact that you must declare a class before you can reference it. Say I have two header file like this...
Header1.h
#include "Header2.h"
#include <deque>
#include <string>
#include <iostream>
using namespace std;
class HelloPackage;
class Hello
{
public:
string Message;
HelloPackage * Package;
Hello():Message("")
{
}
Hello(string message, HelloPackage * pack)
{
Message = message;
Package = pack;
}
void Execute()
{
cout << Message << endl;
//HelloPackage->NothingReally doesn't exist.
//this is the issue essentially
Package->NothingReally(8);
}
};
Header2.h
#include "Header1.h"
#include <deque>
#include <string>
#include <iostream>
using namespace std;
class HelloPackage
{
public:
deque<Hello> Hellos;
HelloPackage()
{
Hellos = deque<Hello>();
}
int AddHello(string Message)
{
Hellos.push_back(Hello(Message,this));
}
void ExecuteAll()
{
for each(Hello h in Hellos)
h.Execute();
}
int NothingReally(int y)
{
int a = 0;
a += 1;
return a + y;
}
}
What I'm wondering is, is there any elegant solution for dealing with these issues? In say c#, and java, you're not restricted by this "linear" compiling.
Use header include guards, either "#ifndef / #define / #endif", or "#pragma once"
Put your code in a .cpp, not inline in the header
???
Profit
The reason this will work for you is because you can then use forward declarations of the class you want to reference without including the file if you so wish.
You are missing include guards
why define methods in the header?
Besides these problems with your code, to answer your question : normal way is to forward declare classes - not to include headers in headers (unless you have to).
If you follow a few basic rules, it is not awkward at all. But in comparison to e.g. Java or C#, you have to follow these rules by yourself, the compiler and/or language spec does not enforce it.
Other answers already noted that, but I will recap here so you have it in one place:
Use include guards. They make sure that your header (and thus your class definition) is only included once.
Normally, you will want to separate the declaration and implementation of your methods. This makes the header files more reusable and will reduce compilation time, because the header requires normally fewer #includes than the CPP (i.e. implementation) file.
In the header, use forward declarations instead of includes. This is possible only if you just use the name of the respective type, but don't need to know any "internals". The reason for this is that the forward declaration just tells the compiler that a certain name exists, but not what it contains.
This is a forward declaration of class Bar:
class Bar;
class Foo {
void foooh(Bar * b);
};
Here, the compiler will know that there is a Bar somewhere, but it does not know what members it has.
Use "using namespace xyz" only in CPP files, not in headers.
Allright, here comes your example code, modified to meet these rules. I only show the Hello class, the HelloPackage is to be separated into header and CPP file accordingly.
Hello.h (was Header1.h in your example)
#include <string>
class HelloPackage;
class Hello
{
public:
Hello();
Hello(std::string message, HelloPackage * pack);
void Execute();
private:
string Message;
HelloPackage * Package;
};
Hello.cpp
#include "Hello.h"
#include "HelloPackage.h"
using namespace std;
Hello::Hello() : Message("")
{}
Hello::Hello(string message, HelloPackage * pack)
{
Message = message;
Package = pack;
}
void Hello::Execute()
{
cout << Message << endl;
// Now accessing NothingReally works!
Package->NothingReally(8);
}
One question that may arise is why is the include for string is needed. Couldn't you just forward declare the string class, too?
The difference is that you use the string as embedded member, you don't use a pointer to string. This is ok, but it forces you to use #include, because the compiler must know how much space a string instance needs inside your Hello class.

Does Not Name A Type in C++

in C++ when i get an error that says xxxxx does not name a type in yyy.h
What does that mean?
yyy.h has included the header that xxxx is in.
Example, I use:
typedef CP_M_ReferenceCounted FxRC;
and I have included CP_M_ReferenceCounted.h in yyy.h
I am missing some basic understanding, what is it?
That seems you need to refer to the namespace accordingly. For example, the following yyy.h and test.cpp have the same problem as yours:
//yyy.h
#ifndef YYY_H__
#define YYY_H__
namespace Yyy {
class CP_M_ReferenceCounted
{
};
}
#endif
//test.cpp
#include "yyy.h"
typedef CP_M_ReferenceCounted FxRC;
int main(int argc, char **argv)
{
return 0;
}
The error would be
...error: CP_M_ReferenceCounted does not name a type
But add a line "using namespace Yyy;" fixes the problem as below:
//test.cpp
#include "yyy.h"
// add this line
using namespace Yyy;
typedef CP_M_ReferenceCounted FxRC;
...
So please check the namespace scope in your .h headers.
The inclusion of the CP_M_ReferenceCounted type is probably lexically AFTER the typedef... can you link to the two files directly, or reproduce the problem in a simple sample?
Although possibly unrelated to OP's original question... this is an error I just had and shows how this error could occur.
When you define a type in a C++ class and you return it, you need to specify the class in which the type belongs.
For example:
class ClassName{
public:
typedef vector<int> TypeName;
TypeName GetData();
};
Then GetData() must be defined as:
ClassName::TypeName ClassName::GetData(){...}
not
TypeName ClassName::GetData(){...}
Otherwise the compiler will come back with the error:
error: 'TypeName' does not name a type
Yes, you should try to check the namespace first.
Be sure you didn't copy paste this yyy.h file from some other class header and keep the same "YYY_H__" in the new #ifndef as in the original file. I just did this and realized my mistake. Make sure to update your new YYY_H__ to represent the new class. Otherwise, obviously, YYY_H__ will already be defined from the original file and the important stuff in this header will be skipped.