I have already searched for this type of error and found a few threads, but each one recommended using #ifndef to make sure the header file is only loaded once. I have done this and still get an error. The odd thing is this error:
circle.cc:25:6: error: prototype for ‘void circle::populate_classobj(int, int, int)’ does not match any in class ‘circle’
says my function only has 3 int's but every place i have that function, i have 4 ints.
here is my class header file
#ifndef _CIRCLE_H_
#define _CIRCLE_H_
#define PI 3.14159
class circle
{
public:
float radius(int x1, int x2, int y1, int y2);
float circumference(float d);
float area(float d);
void populate_classobj(int, int, int, int);
protected:
float distance(int x1, int x2, int y1, int y2);
private:
int x1, y1, x2, y2;
};
#endif // _CIRCLE_H_
Here is my function call in my class file circle.cc
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
{
x1=cx1;
x2=cx2;
y1=cy1;
y2=cy2;
}
and here is what i actually call in main
mycircle.populate_classobj(x1,x2,y1,y2);
there are variables called x1, x2, y1, y2 in main
The really odd thing is that the redefinition error is only for cy1, not cx1, cx2 or cy2
Thanks for any help and if you need to see more of my code, ask for it.
-Will
Last two parameters are exactly same as shown below. Hence the redefinition error.
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
^^^ ^^^
I think you wanted to write:
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy2)
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
You see there the redefinition of cy1, since both last arguments are called the same. By the way, names beginning with an underscore in the global namespace are reserved for the implementation, you should drop the leading underscore from your scope guards.
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
// ^^^ ^^^
Is this a question typo, or do you really have two parameters in the function definition named cy1?
Your definition of populate_classobj uses the same name cy1 for two different parameters.
Related
I have tried to use overload with floating and integer. When I only used the integer, the code worked fine, but when I included the floating it gave me errors. The code is the following:
#include <iostream>
using namespace std;
int calculate(int x,int y);
float calculate(float x,float y);
const int MAININT=4;
int main()
{
int result=calculate(5,5);
float fresult=calculate(7.5,7.5); LINE X
cout << (result + MAININT + fresult); LINE Y
return 0;
}
int calculate(int x,int y)
{
int result=x*y;
return result;
}
float calculate(float x,float y)
{
int result=x*y;
return result;
}
By deleting LINE X and fresult from LINE Y, the code give me no errors. So I assume there must be something wrong in LINE X, but I don't understand why I get errors.
The error messages I got was :
[Error] call of overloaded 'calculate(double, double)' is ambiguous
[Note] candidates are:
[Note] int calculate(int, int)
[Note] float calculate(float, float)
I did not understand the error messages, so I didn't include them. I understand what I did wrong from the answer of songyuanyao, but next time I will include the error messages in my question from the start so it will be easier to see what I have done wrong in the code.
Because 7.5 is a double (see floating point literal), not a float; and implicit conversion to int or float are considered as the same ranking.
If your suppose 7.5 as float here you could use the suffix f or F to make it a float literal. e.g.
float fresult = calculate(7.5f, 7.5f); // 7.5f is a float literal; no ambiguity
Or use explicit conversion:
float fresult = calculate(static_cast<float>(7.5), static_cast<float>(7.5));
You should have posted the error message which is self-explanatory in itself. The error message mentions about the candidate functions and how they are not exactly compatible:
error: call of overloaded 'calculate(double, double)' is ambiguous
float fresult=calculate(7.5,7.5);
^
note: candidate: int calculate(int, int)
int calculate(int x,int y);
^
note: candidate: float calculate(float, float)
float calculate(float x,float y);
By default, a floating-point literal (7.5 in your case) is of type double.
Here is the list of suffix that determines the type of the floating-point literal:
(no suffix) defines double
f F defines float
l L defines long double
While others have already told you where the ambiguity error comes from, I'm surprised nobody has mentioned the easiest solution to the problem: Just use double instead of float.
Just like int should be your default choice for integer numbers, double should be your default choice for floating-point numbers. float is for very special use cases, none of which are likely to apply in your situation. See "When do you use float and when do you use double" over at Software Engineering Stack Exchange.
As a side effect of following this guideline, your particular problem here disappears:
#include <iostream>
using namespace std;
int calculate(int x,int y);
double calculate(double x, double y);
const int MAININT=4;
int main()
{
int result=calculate(5,5);
double fresult=calculate(7.5,7.5);
cout << (result + MAININT + fresult);
return 0;
}
int calculate(int x,int y)
{
int result=x*y;
return result;
}
double calculate(double x, double y)
{
double result=x*y; // the `int` here was a mistake in your original code anyway
return result;
}
Some further suggestions:
Avoid using namespace std;.
Reserve ALL_CAPS for preprocessor macros.
I'm trying to create the contructors for line but I keep getting this error even though this worked on the poolball class and was able to run before adding line.cpp and line.h. Also, this is code from class, and i have no idea why it is not compiling.
#include "Line.h"
Line::Line(){
}
Line::Line( int x1, int y1, int x2, int y2){
}
void Line::setPos(int x1, int y1, int x2, int y2){
}
void Line::draw( void ){
}
-------------------------------------------------------------------------
#pragma once
class Line{
public:
int x1;
int y1;
int x2, y2;
//constructor
Line();
Line( int x1, int y1, int x2, int y2);
//methods
void setPos(int x1, int y1, int x2, int y2);
void draw( void);
This is the error I get when trying to build and run
||=== Build: Debug in 10.19class (compiler: GNU GCC Compiler) ===|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|2|error: extra qualification 'Line::' on member 'Line' [-fpermissive]|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|2|error: 'Line::Line()' cannot be overloaded|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.h|10|error: with 'Line::Line()'|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|5|error: extra qualification 'Line::' on member 'Line' [-fpermissive]|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|5|error: 'Line::Line(int, int, int, int)' cannot be overloaded|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.h|11|error: with 'Line::Line(int, int, int, int)'|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|9|error: extra qualification 'Line::' on member 'setPos' [-fpermissive]|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|9|error: 'void Line::setPos(int, int, int, int)' cannot be overloaded|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.h|13|error: with 'void Line::setPos(int, int, int, int)'|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|12|error: extra qualification 'Line::' on member 'draw' [-fpermissive]|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|12|error: 'void Line::draw()' cannot be overloaded|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.h|14|error: with 'void Line::draw()'|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|13|error: expected '}' at end of input|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp||In constructor 'Line::Line(int, int, int, int)':|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|6|error: 'cout' is not a member of 'std'|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|6|error: 'endl' was not declared in this scope|
C:\Users\Admin\Desktop\C++Projects\10.19class\Line.cpp|13|error: expected unqualified-id at end of input|
||=== Build failed: 16 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Judging by the error messages, and assuming the stuff below the dashes is the full contents of your header file, then your problem is that you're missing }; at the end of your header file. You need to close your class definition with the close bracket and semicolon in your header, before you can implement the functions in your Line.cpp file.
void Line(void) is not true,constructors have no return type and in parameter list you shouldn't write void,either.
I have two classes, and this is the header of one of them:
#ifndef WRAPPER_HPP
#define WRAPPER_HPP
#include <SDL/SDL.h>
using namespace std;
class Wrapper
{
private:
//SDL_Surface *screen;
public:
static SDL_Surface *screen;
static void set_screen(SDL_Surface *_screen);
static void set_pixel(int x, int y, Uint8 color);
static void clear_screen(int r, int g, int b);
static SDL_Surface* load_image(char path[500]);
static void draw_image(SDL_Surface *img, int x, int y, int width, int height);
static void draw_line(int x1, int y1, int x2, int y2, Uint8 color);
};
#endif
I am calling Wrapper::set_screen(screen) from another file and I get this error:
In file included from /home/david/src/aships/src/Wrapper.cpp:6:0:
/home/david/src/aships/src/Wrapper.hpp: In static member function ‘static void Wrapper::set_screen(SDL_Surface*)’:
/home/david/src/aships/src/Wrapper.hpp:11:18: error: invalid use of member ‘Wrapper::screen’ in static member function
/home/david/src/aships/src/Wrapper.cpp:10:3: error: from this location
I also get a similar error for the definition of every single function on Wrapper.cpp, for example:
void Wrapper::set_pixel(int x, int y, Uint8 color)
{
/* Draws a pixel on the screen at (x, y) with color 'color' */
Uint8 *p;
p = (Uint8 *) screen->pixels + y * screen->pitch + x * screen->format->BytesPerPixel;
*p = color;
}
On compile:
/home/david/src/aships/src/Wrapper.hpp: In static member function ‘static void Wrapper::set_pixel(int, int, Uint8)’:
/home/david/src/aships/src/Wrapper.hpp:11:18: error: invalid use of member ‘Wrapper::screen’ in static member function
/home/david/src/aships/src/Wrapper.cpp:17:17: error: from this location
I know it's related to the class being static and thus the variable Wrapper.screen is not accessible or something, but I'm not sure of how to fix it. Any ideas?
You are using a static variable
static SDL_Surface *screen;
in your code.
In C++ when you declare a static variable in the .h (or .hpp) you are creating a variable that is general (static) to the class. Thus, to use it in another file you have to redeclare it (which I'm guessing you didn't) to create a variable in that file referencing the static one. In your case put this:
SDL_Surface* Wrapper::screen;
in the .cpp file.
I'm not sure the theory is well explained, but it works like that.
Your class and member (screen) are not static, which means they don't actually exist.
You can't access a non static member in a static function.
Try to make your data members to be static.
I'm not convinced that the code abstract you show us is an accurate characterization of your problem.
Your header should not include using namespace std; — it doesn't use or declare anything from the std namespace, and specifying using namespace std; is generally regarded as 'not a good idea', doubly so when it appears in a header file.
It also isn't clear that your header needs to include SDL/SDL.h. If the Uint8 type is easily isolated (not necessarily valid), then your header file can simply use a forward declaration of the SDL_Surface class. (Your implementation code will need to include SDL/SDL.h; but you should not burden the users of your wrapper class with unnecessary #include directives when simple forward declarations would suffice.)
This code is self-contained (does not need any headers), but more or less simulates what you could use, and it compiles OK:
#ifndef WRAPPER_HPP
#define WRAPPER_HPP
typedef unsigned char Uint8;
class SDL_Surface;
class Wrapper
{
public:
static SDL_Surface *screen;
static void set_screen(SDL_Surface *_screen);
static void set_pixel(int x, int y, Uint8 color);
static void clear_screen(int r, int g, int b);
static SDL_Surface *load_image(char path[500]);
static void draw_image(SDL_Surface *img, int x, int y, int width, int height);
static void draw_line(int x1, int y1, int x2, int y2, Uint8 color);
};
#endif
//#include <SDL/SDL.h>
typedef unsigned short Uint16;
class SDL_Surface
{
public:
Uint8 *pixels;
Uint16 pitch;
struct
{
Uint8 BytesPerPixel;
} *format;
};
// End of SDL/SDL.h
void Wrapper::set_pixel(int x, int y, Uint8 color)
{
/* Draws a pixel on the screen at (x, y) with color 'color' */
Uint8 *p;
p = (Uint8 *) screen->pixels + y * screen->pitch + x * screen->format->BytesPerPixel;
*p = color;
}
It also compiles without warnings. The (Uint8 *) cast (copied from the original) is unnecessary. With the class definition given, it is superfluous; if you are needing to use a cast because the type of the pixels member of SDL_Surface actually isn't Uint8, are you sure it is a good idea? And can't you use reinterpret_cast<Uint8>(screen->pixels) instead to make it clearer?
Can you reduce your problem to code analogous to this that still shows the actual error?
//class.h
typedef double (*ffunct)(double x1, double y1, double x2, double y2);
class Class {
public:
static ffunct myfunct;
static void setFunct();
static double doSomething(double x1, double y1, double x2, double y2);
static void call();
}
//class.cpp
void Class::setFunct(){
Class::myfunct=Class::doSomething;
}
double Class::doSomething(double x1, double y1, double x2, double y2) {
cout << "Hello World" << endl;
}
void Class::call() {
Class::myfunct(1.0,2.0,3.0,4.0);
}
//main.cpp
…
Class::setFunct();
Class::call();
…
Running the programm results in Undefined symbols for architecture x86_64: "Class::myfunct", referenced from Class::setFunct, Class::call…
So what am I doing wrong?
In your cpp file you need one more line:
ffunct Class::myfunct = NULL;
The class declaration said that the variable would exist somewhere but you never gave it a definition. Since it's not part of each object it has to be defined separately.
Your prototype of doSomething has a return type of double, but your implementation thereof has a return type of void.
static double doSomething(...)
...
void Class::doSomething(...)
Fixing this won't clear all the errors however. You still have a few more as the other answers mention.
static ffunct myfunct; is a declaration
You need a definition of it also in the cpp file
ffunct Class::myfunct;
add one line on the top of your .cpp file:
ffunct Class::myfunct=NULL;
I'm developing my code using C++ and want to use MPFIT nonlinear curve fitting library, which is developed in C but allows to compile in C++.
For example I have a class named "myClass", and this class has a function myClass::Execute()
I include "mpfit.h" to myClass.h file. And try to call a function called mpfit from Execute().
int status = mpfit(ErrorFunction, num1, num2, xsub_1D, 0, 0, (void *) &variables, &result);
The problem is ErrorFunction is a function of myClass. So compiler gives error when I try to use this. I tried to carry the ErrorFunction out of the class object, but this time I take the error given below:
Error when the ErrorFunction is outside of the class:
Error 4 error C2664: 'mpfit' : cannot convert parameter 1 from 'int
(__cdecl *)(int,int,double *,double,double *,void *)' to
'mp_func'
Error when the ErrorFunction is inside the class:
Error 3 error C3867: 'myClass::ErrorFunction': function call missing argument list; use '&myClass::ErrorFunction' to
Definition of error function:
int ErrorFunction(int dummy1, int dummy2, double* xsub, double *diff, double **dvec, void *vars)
How can I call this function and parse it into mpfit, which is a C function?
mp_func is defined as:
/* Enforce type of fitting function */
typedef int (*mp_func)(int m, /* Number of functions (elts of fvec) */
int n, /* Number of variables (elts of x) */
double *x, /* I - Parameters */
double *fvec, /* O - function values */
double **dvec, /* O - function derivatives (optional)*/
void *private_data); /* I/O - function private data*/
Make sure that your calling conventions match. C libraries use the C calling convention, or cdecl (__cdecl). If you're using the mp_func typedef within C++, it could be defaulting to the compiler's standard calling convention, or stdcall (__stdcall). Either make a new typedef or change it to the following:
typedef int __cdecl (*mp_func)(int m, /* Number of functions (elts of fvec) */
int n, /* Number of variables (elts of x) */
double *x, /* I - Parameters */
double *fvec, /* O - function values */
double **dvec, /* O - function derivatives (optional)*/
void *private_data); /* I/O - function private data*/
And when you declare ErrorFunction, also declare it as __cdecl:
int __cdecl ErrorFunction(int, int, double*, double *, double **, void *);
If the compiler still complains when calling the mpfit function, you can try casting your function pointer to the mp_func typedef with cdecl:
int status = mpfit((mp_func)ErrorFunction, num1, num2, xsub_1D, 0, 0, (void *) &variables, &result);
Given the definitions of mpfit() and mp_func that you have shown, you would need to use the private_data parameter of mp_func to pass your class's this pointer around. You are currently using that parameter to pass your variables item around instead. Make variables be a member of your class (if it is not already) and then pass this to mpfit() instead:
class MyClass
{
private:
TheDataType variables;
static int ErrorFunction(int m, int n, double *x, double *fvec, double **dvec, MyClass *pThis);
public:
void DoIt();
};
void MyClass::DoIt()
{
// ...
int status = mpfit((mp_func)&ErrorFunction, num1, num2, xsub_1D, 0, 0, this, &result);
// ...
}
int MyClass::ErrorFunction(int m, int n, double* x, double *fvec, double **dvec, MyClass *pThis)
{
// use pThis->variables as needed ...
}
Or:
class MyClass
{
private:
static int MPFitErrorFunction(int m, int n, double *x, double *fvec, double **dvec, MyClass *pThis);
int MyErrorFunction(int m, int n, double *x, double *fvec, double **dvec);
public:
void DoIt();
};
void MyClass::DoIt()
{
// ...
int status = mpfit((mp_func)&MPFitErrorFunction, num1, num2, xsub_1D, 0, 0, this, &result);
// ...
}
int MyClass::MPFitErrorFunction(int m, int n, double* x, double *fvec, double **dvec, MyClass *pThis)
{
return pThis->MyErrorFunction(m, n, x, fvec, dvec);
}
int MyClass::MyErrorFunction(int m, int n, double* x, double *fvec, double **dvec)
{
// use this->variables as needed ...
}
Looks like instead of:
int ErrorFunction(int dummy1, int dummy2, double* xsub, double diff, double *dvec, void *vars)
it should be:
int ErrorFunction(int dummy1, int dummy2, double* xsub, double *diff, double **dvec, void *vars)
to match your
typedef int (*mp_func)(int m, /* Number of functions (elts of fvec) */
int n, /* Number of variables (elts of x) */
double *x, /* I - Parameters */
double *fvec, /* O - function values */
double **dvec, /* O - function derivatives (optional)*/
void *private_data); /* I/O - function private data*/
Your callback must be declared extern "C" for this to work.
Edit: I see people are having hard time grasping this fact. The standard says (7.5/1):
Two function types with different language linkages are distinct types
even if they are otherwise identical.
There's a standard idiom for C++ - to - C, using the pimpl idiom:
foo_c.h:
#ifdef __cplusplus
extern "C" {
#endif
//forward declaration. clients of foo_c.h should only hold pointers to Foo_c
typedef struct Foo_c Foo_c;
int someMethod(Foo_c* foo);
#ifdef __cplusplus
}
#endif
foo_c.cpp:
#include <foo.h>
struct Foo_c {
Foo foo;
}
int someMethod(Foo_c* foo) {
try {
foo->foo.someMethod();
return 0; //no error
}
catch(...) {
return 1; //error
}
}
(Edited for extern "C"'s per below answer.)