I am trying to implement a function class, but got a error of redefinition. I know it is stupid, but can anyone please help?
=== header file ===
#ifndef _NS4_h
#define _NS4_h
#include <vector>
#include <list>
namespace NS4{
class complex{
double r, i;
public:
complex(double a=0, double b=0) : r(a), i(b) {};
complex operator+(complex c);
complex &operator+=(complex c);
complex &operator=(complex c);
};
// function class
class Add{
complex val;
public:
Add(complex c){ val = c; }
Add(double r, double i) { val = complex(r, i); }
void operator()(complex& c) const { c += val; }
};
void h(std::vector<complex> &aa, std::list<complex> ll, complex z);
}
#endif
=== Part of the cpp file ===
using namespace NS4;
void test9()
{
vector<complex> aa;
aa.push_back(complex(0,1));
aa.push_back(complex(0,2));
aa.push_back(complex(0,3));
list<complex> ll;
ll.push_back(complex(1,1));
ll.push_back(complex(1,2));
ll.push_back(complex(1,3));
complex zz(1,1);
// the following line is not working
// error C2371: 'zz' : redefinition; different basic types
Add(zz); // Add(complex(1,1)) is working.
h(aa,ll, zz);
}
You have an Add class, so you need to create an instance of it, in order to call the constructor.
So in the below case, a is an instance of our Add class.
Add a(zz);
You can optionally put parenthesis around the variable name in a declaration.
int (i);
is the same as
int i;
So in your case you are declaring a variable named zz of type Add, and a variable named zz already exists. You probably meant to pass zz as an argument to Add constructor, but then you should give some name to the variable:
Add adder(zz);
However, I don't see where that instance is used at all.
But if you just want to invoke the constructor of Add without declaring a variable, you can put parenthesis around the whole expression:
(Add(zz)); //just calls Add::Add(Complex);
Welcome to C++ ;)
What is Add(zz) supposed to mean? What do you think it means?
Add(zz) is actually a declaration of object zz of type Add, i.e.
Add(zz);
is equivalent to
Add zz;
You have already defined zz before, which is why you get the redefinition error. No surprise here.
There's no way to help you further without knowing what you were trying to do by that Add(zz) line.
Related
First of all, let me say I have read similar threads on how to initialize a global variable or how to properly implement global constants. Nevertheless, these questions did not really help me with my concrete problem, as also haven't any other ressources I've consulted. The problem is the following.
I (have to) declare in a header file header.h a variable that must be constant and used by the main function in main.cpp as well as other functions defined in a another file functions.cpp (that are previously declared in header.h). The problem is this constant is a runtime constant, whose value is given by the user. How should I proceed?
I think my best shot was to do as follows. In header.h
// Header guard
namespace n
{
// Some forward declarations
extern const double mu; // The constant that should be initialized by the user.
// Some other declarations
}
then in functions.cpp
#include "header.h"
namespace n
{
// Some definitions here
double function_that_uses_mu(double a, double b)
{
// Some code using mu
return somedouble;
}
// Some other definitions
}
finally main.cpp
#include "header.h"
#include <iostream>
int main()
{
// Some code
double value_of_mu{};
std::cin >> value_of_mu;
// Validity check
extern const double n::mu{ value_of_mu };
// More code
return 0;
}
The problem is that compilation fails due to the fact that error: ‘mu’ has both ‘extern’ and initializer. However, if I tried mu = value_of_mu I would obviously get an error because I would be assigning to a const value (not initialising it). So I don't know how to proceed, or what's wrong with my code. There are two mandatory facts I must respect:
Functions/global-consts definitions, functions/global-consts declarations and main must be split in the three aforementioned files.
mu is to be defined as a constant shared by all three files.
Is this possible? How?
EDIT:
I think my problem is that an exten variable can't be initialised inside a function, but if this is so, I don't see how I do what I'm trying to.
Think about it: If a value needs to be set during the lifetime of a program, it's not really a constant. So, you shouldn't try to pretend it's a constant by declaring it as const. If you don't want the program to accidentally change its value, you have to protect it in some other way, such as making it a private member variable of a class. That way, you can restrict access to only return the value of mu as a const.
// muholder.h
class muholder
{
private:
double m_value;
public:
muholder (double ivalue): m_value(ivalue) {}
double const &value() const { return m_value; }
};
// workflow_envelope.h
class workflow_envelope
{
private:
muholder m_mu;
public:
workflow_envelope (double imu): m_mu(imu) {}
bool validity_check();
double method_that_uses_mu (double a, double b) const { return a*m_mu.value()/ b; }
void run(); // any "more code" goes in here.
};
// main
#include "workflow_envelope.h"
#include <iostream>
int main()
{
// Some code
double value_of_mu;
if (std::cin >> value_of_mu)
{
// Validity check
workflow_envelope workflow(value_of_mu);
if (workflow.validity_check())
{
workflow.run();
return 0;
}
}
return 1;
}
When you initialize a variable, you can't specify extern. This should work instead:
int main()
{
// Some code
double value_of_mu{};
std::cin >> value_of_mu;
// Validity check
using namespace n;
const double mu = value_of_mu; // no extern specifier
// More code
return 0;
}
I can't get this constructor right (RMatrix.class.h) :
RMatrix (_3DVec& Wup, _3DVec& Out, double Spin) {
// ...
}
My main file has :
#include <iostream>
#include <math.h>
#include "classes/Color.class.h"
#include "classes/Vector.class.h"
#include "classes/RMatrix.class.h"
int main () {
// ...
}
_3DVec is defined defined in Vector.class.h and included before the RMatrix file.
Compiler throws : error: no matching function for call to ‘_3DVec::_3DVec()’.
RMatrix file code :
class RMatrix {
private:
_3DVec right;
_3DVec up;
_3DVec out;
double spin;
double MData[16];
public:
RMatrix (_3DVec& Wup, _3DVec& Out, double Spin) {
// stuff...
}
}
Thanks
The compiler is telling you that somewhere in your code the default constructor of _3DVec class is needed. And class _3DVec does not have a default constructor. Hence the error.
In the code you posted RMatrix members right, up and out are default-constructed by RMatrix constructor. So, this is exactly where the default constructor is required.
I could make a guess that constructor parameters are supposed to be used as initializers to your vectors, as in
RMatrix (_3DVec& Wup, _3DVec& Out, double Spin) : up(Wup), out(Out) {
// stuff...
}
The above takes care of up and out by copy-constructing up and out, but that still leaves your right default-constructed. And that is still a guess. Only you know how what your class members are supposed to be initialized with.
P.S. Note also that in C++ language global-namespace names that begin with _ are reserved to implementation. You are not allowed to use such names in global namespace.
I am trying to write classes and structs in C++, for example:
using namespace std;
struct Position {
int x;
int y;
};
class Maze {
Position pos;
pos.x = 0;
pos.y = 0;
};
int main() {
return 0;
}
but it rises some errors when I try to compile it:
(gcc version 4.3.2)
10: error: ISO C++ forbids declaration of 'pos' with no type
10: error: expected ';' before '.' token
11: error: ISO C++ forbids declaration of 'pos' with no type
11: error: expected ';' before '.' token
It looks like this piece of code is pretty much the same as it in C++ Tutorial: Struct.
Answers to some other posts about "error: ISO C++ forbids declaration of '...' with no type" (such as this) suggest to add namespace, but I find it hard see what is the reason why it does not work here.
In summary, I have the following questions:
What does this error actually mean in this case?
What does this error mean in general?
Why this code does not work?
How to make it work?
I will be grateful if someone could give an answer, and/or a direction of research/reading.
This code
pos.x = 0;
pos.y = 0;
needs to go in a function. One way would be to put it in the constructor, something like:
class Maze {
Position pos;
public:
Maze() {
pos.x = 0;
pos.y = 0;
}
};
Note that I made the constructor public as otherwise you wouldn't be able to use the Maze class
Edit: Actually answering your questions:
What does this error actually mean in this case?
The compiler doesn't know what to do with pos.x = 0 as it is expecting declarations at this point, not code.
What does this error mean in general?
It usually means that the compiler doesn't know how to process the declaration you wrote.
Why this code does not work?
Because you put executable code where declarations are supposed to go.
How to make it work?
See the code above.
Since this question is titled "ISO C++ forbids declaration of “something” with no type", here's a more generic answer. C++ is unable to find the type, so just specify the type.
In my case, I was able to solve it only after adding a forward declaration.
A.hpp
class A
{
};
B.hpp
#include "A.hpp"
class B
{
public:
A* inst;
};
This caused the error of ISO C++ forbids declaration of A with no type.
So I made a change in B.hpp as such:
#include "A.hpp"
class A;//the forward declaration
class B
{
public:
A* inst;
};
and it compiled fine!
For a start, you cannot initialise the members at the top level of the class:
class Maze {
Position pos;
pos.x = 0;
pos.y = 0;
};
You have to provide a constructor of some sort and, if you're after a default state for the position, that's probably where you want the initialisation done. Objects should generally be responsible for their own initialisation and tear-down:
using namespace std;
struct Position {
int x;
int y;
Position() : x(0), y(0) {}
};
class Maze {
Position pos;
};
int main () {
return 0;
}
Lines 10 and 11 are
pos.x = 0;
pos.y = 0;
The compiler is assuming that you wanted to declare variables named 'pos.x' and 'pos.y', and is complaining because you haven't told it what type those variables are.
What want to do is to move those two assignments inside a constructor, just as The Dark suggests.
However, if I wasn't sure how complex things might get later on, I might write it this way:
class Position {
private:
int x;
int y;
public:
Position(int x0, int y0) : x(x0), y(y0) {
// Any other initialization here.
}
inline int getX() { return x; }
inline int getY() { return y; }
inline void setX(int x0) { x = x0; }
inline void setY(int y0) { y = y0; }
}
class Maze : public Position {
Maze() : Position(0,0) {
// Any other initialization here.
}
}
Some may say that this is overkill. It may well be, I don't know how complex your final problem really is. If you don't know for sure either, going with a class is probably safest.
The whole point to classes is data encapsulation. Don't expose anything you don't have to, and that way you don't have to worry about some other code changing values in ways you didn't expect. Using a struct may be sufficient, but if it isn't, going back and converting from a struct to a class may be more difficult than just going ahead with a class now.
Sometimes I come across situations where I need to execute a set of code multiple times but with slight modifications. Consider 2 following cases:
Case 1:
A
B
C
Case 2:
A
D
C
//A, B, C, D are used to represent a set of code lines
Now there is no similarity between the lines of code in B & D so I am creating 2 different functions currently in my application.
However the size of code in B or D is very small in comparison to A or C.
I cannot create separate functions just for A & C because they use some common variables and it would be very messy to pass these variables as arguments.
So it looks like there is only a single solution to my problem.
Combine both the cases into a single function and choose between one of these cases by passing a bool as argument to this function. This however results in a very large size function to maintain.
So I am looking for some better alternatives as I am sure many people must have come across such situations.
EDIT:
consider just for the sake of simplicity a string variable myString.
A intialises it with some value.
B/D modify it according to some conditions.
C uses myString for some purpose, say write to file.
All in all there is flow of data like this:
Case 1:
A -> B -> C
Case 2:
A -> D -> C
Just that there is flow of a lot of data to separate each of these sets to different functions.
Options I can think of:
Create a class with A, B, C and D as functions.
All the common variables can be member variables of this class.
Create a class that simply stores all the common variables.
This can be passed by reference to A, B, C and D (so you would just pass a single variable).
Consider trying to refactor them so you minimize the number of common variables they use.
This can be done in addition to either of the above, or by itself.
Without knowing what exactly you are doing, I can't really tell you whether or not this is viable, but you should keep it in mind. While the above-mentioned parameter class is just a single variable, it's essentially just a wrapper for a bunch of variables - one should still attempt to minimize the amount of them.
One thing that you can do is define B and D as functor classes:
// this is a functor
struct B_add {
B_add(int x) : x_(x) {}
int operator()(int y) { return x_ + y; }
void set_x(int x) { x_ = x; }
private:
int x_;
};
struct D_mult {
D_mult(int x) : x_(x) {}
int operator()(int y) { return x_ * y; }
void set_x(int x) { x_ = x; }
private:
int x_;
};
Then inside the long_function_that_takes_either_B_or_D
template <typename F>
void long_function_that_takes_either_B_or_D(F & f)
{
A...
f.set_x(result_of_a);
int result_for_c = f(); //B or D
C...
}
Main:
int main(int argc, char **argv) {
long_function_that_takes_either_B_or_D(B_add(42));
long_function_that_takes_either_B_or_D(D_mult(24));
return 0;
}
It brakes OO design but i think you can try to arrange it into one class
#include <stdio.h>
class SimpleClass
{
public:
SimpleClass(void){}
void someFunction(void (* zprintf)(const char *) ) //zprintf is pointer to B or D functionality
{
printf("calling zprintf function\n"); //This is your A code
zprintf("hey");
printf("called zprintf function\n"); //This is your C code
}
~SimpleClass(void)
{}
};
And then use it like this :
void zprintf1(const char * str )
{
printf("i'm printing %s\n", str);
}
void zprintf2(const char * str )
{
printf("I don't want to print %s\n", str);
}
.
.
.
SimpleClass simpleClass;
simpleClass.someFunction(zprintf1);
simpleClass.someFunction(zprintf2);
It is a hack i know, but you can make it more pretty.
Use defines to generate code.
// A
if (runB)
// B
else
// D
// C
I'm trying to instantiate a few classes, with references to the first class passed along.
The compiler gives me an error stating: error: 'classData' is not a type.
ClassData hold some complicated data structures and has a bunch of accessors to that data. ClassFunc has a bunch of functions that operate on that data. Then the Work class does a bunch of work and occasionally needs to call a function in ClassB that will do some work on the data in ClassData.
Below is the code:
/////////////////////////
//ClassData.h
class ClassData {
public:
ClassData(){
// initialize a bunch of stuff
};
virtual ~ClassData(){};
}
/////////////////////////
//ClassFunc.h
#include "ClassData.h"
class ClassFunc {
public:
ClassFunc(ClassData& in_classData) : classData(in_classData){};
virtual ~ClassFunc();
float updateEta(float deltaVJ, int column);
private:
ClassData& classData;
};
/////////////////////////
//ClassFunc.cpp
#include "ClassFunc.h"
float ClassFunc::updateEta(float a, int b){
float foo = 0.0
// Do a bunch of work to foo
return foo;
};
/////////////////////////
// Work.h
#include "ClassData.h"
#include "ClassFunc.h"
class Work{
public:
Work(ClassData& in_class) : classData(in_class){
// initialize some stuff
};
~Work(){};
float updateTheta(int a, float b, float c);
private:
ClassData& classData;
ClassFunc classFunc(classData); //// ERROR IS HERE
}
/////////////////////////
// Work.cpp
#include "Work.h"
float Work::updateTheta(int a, float b, float c){
// do some work first
double foo = classFunc.updateEta(d, e);
return foo
};
Your compiler's right: classA isn't a type. C++ is case-sensitive; ClassA is the type you're looking for (check the first line of ClassB's constructor).
Hope that helps!
Answer After question modification
ClassFunc classFunc(classData); is not valid syntax in the definition of a class. You will need to have this classFunc variable by either a set function or through the constructor.
However, writing just a setter will be difficult because your ClassFunc requires a ClassData. In order to work around this, you may need to modify your ClassFunc also.
Also, there is another error. ClassData and Work are missing a ; at the end of its definition.
Original Answer before question modification
There are several errors in this code. Such as
float ClassA::funcA{
Should be
float ClassA::funcA(){
As other wise, it looks like a function definition.
Second, there is
ClassB(Class A& in_classA): classA(in_classA){
As it should be
ClassB(ClassA& in_classA): classA(in_classA){
As Class A is not a type.
Also, you are missing several semicolons but those should be obvious to spot.
The problem is that you cannot initialize member variables in the class declaration:
ClassFunc classFunc(classData);
Instead, initialize it in the initializer list of the constructor:
Work(ClassData& in_class) : classData(in_class), classFunc(classData) {}