C++ Default Constructor Not Found - c++

I'm having a problem with some code in Visual C++ 2010 Express. I'm trying to make a class that has a constructor that accepts an argument which has a default value. Here's a short program that shows what I'm trying to achieve:
//Class declaration
class Class {
private:
int mValue;
public:
Class(int);
int GetValue();
};
Class::Class(int val=1) : mValue(val)
{
}
int Class::GetValue()
{
return mValue;
}
int main()
{
Class test;
cout << test.GetValue() << endl;
}
Now this seems to work fine. If I replace Class test with Class test(10), say, mValue is initialised correctly.
However, in a second program I'm trying to do exactly the same thing. I have a class defined like this:
namespace mobs {
Class Monster {
private:
mHitPoints;
public:
Monster(int);
int GetHitPoints() const;
};
}
with the implementation of the functions like this:
namespace mobs {
Monster::Monster(int hp=10) : mHitPoints(hp)
{
}
int Monster::GetHitPoints() const
{
return mHitPoints;
}
}
but when I try to declare a class and use the GetHitPoints() function like so:
mobs::Monster testmonster;
cout << testmonster.GetHitPoints() << endl;
Visual C++ tells me that "no default constructor exists for class mobs::Monster". Why is this?

The default value belongs in the declaration, not the definition. Move the =10 to your header file:
Monster(int hp = 10).
In the implementation, you don't even need the default value. I usually use:
Monster::Monster(int hp /*=10*/)
just to make it clear there's a default.

The constructor is ambigious. that's why.
if you have two constructors
Monster(){}
Monster(x=10){}
and you make a call
Monster m();
How should the compiler know whether you mean the first or second constructor
Instead Define it as follows
class Class {
private:
int mValue;
public:
Class(int val) :mValue(val){}
Class() :mValue(1){}
};

Related

Named Parameter Idiom using a pointer to a class private method

I got stuck with a C++ compilation error while doing something that is probably not really "conventional".
To make things easier I just re-wrote the mechanism I am trying to use in a easier-to-read way and I checked that I got the same issue.
First of all here is the code:
test.h // -- C++ --
template <typename MODULE> class item;
template <typename MODULE>
class init {
public:
typedef int (MODULE::*funcPtr)(int);
private:
funcPtr m_fp;
public:
init& has_funcPtr(funcPtr fp) { m_fp = fp;}
init() {}
virtual ~init() {}
private:
friend class item<MODULE>;
};
template <typename MODULE>
class item {
public:
typedef int (MODULE::*funcPtr)(int);
private:
funcPtr m_fp;
public:
item(init<MODULE> params) : m_fp(params.m_fp) {}
virtual ~item() {}
};
class user {
public:
typedef init<user>::funcPtr funcPtr;
private:
// Method CB
int func1(int i);
// Item member
item<user> m_item;
public:
user();
virtual ~user();
};
test.cpp // -- C++ --
#include "test.h"
user::user() : m_item(init<user>().has_funcPtr(this->func1) ) {}
int user::func1(int i) {return 1;}
and here is the error:
/test.cpp:5:59: error: invalid use of non-static member function
user::user() : m_item(init<user>().has_funcPtr(this->func1) ) {
^
So, I am not sure this is the best way to achieve what I want (probably not, anyway if you have other suggestions they are very welcome) but my goal now is to make it work or to understand exactly why it can't work so that I learn something from it!
The basic idea is that:
the class "item" can be initialized with the named parameter idiom using the method "has_funcPtr" of the class "init" concatenated to its constructor like: "init().has_funcPtr(&function_name)".
the class "user" can store a pointer to its private method "func1" as a private member of its private member of type "item".
In this way, when a specific method of an object "item" is called (for simplicity I don't include this long part here since it is not relevant to the error but it is just to describe the goal of this snippet of code) that method can do stuff and call the private method of its father object "user" through that pointer to function (I hope this is clear enough...).
Now, I think there is an issue with the order of initialization of the objects but I am not sure where and how to fix it.
In particular I thought that since the "func1" method doesn't operate on any member of the class "user", then its reference could be used directly in the initialization list to initialize an "init" object and feed it to an "item" object.
Thank you all in advance
this->func1 doesn't form a member function pointer. It should look like &user::func1 if you are in the user class.
I post here the complete answer to my issue. I developed it after the suggestion from Bo and after understanding how to point to an instance specific method through a pointer to it.
In short, two things are really important to note:
A pointer to a non-static class member function could be thought at as just an offset rather than an "absolute address" (http://www.codeguru.com/cpp/cpp/article.php/c17401/C-Tutorial-PointertoMember-Function.htm). This means that you can't access that function (it is just an offset) without first having an instance pointer. Once you have the instance pointer, with this "offset pointer" you can call that method using:
(object_ptr->*method_ptr)(parameters_here)
A better way would be to use a #define macro since this syntax is really error prone and complex to read (https://isocpp.org/wiki/faq/pointers-to-members):
#define CALL_MEMBER_FN(ptrToObject,ptrToMember) ((ptrToObject)->*(ptrToMember))
and then use it as:
CALL_MEMBER_FN(object_ptr, method_ptr)(parameters_here)
Following the first point, if you want a nested class to be able to call the upper class method by a pointer to it, you also need to pass the upper class instance pointer to access that function. In my case, since I wanted to be able to decide case by case if that method should be called or not, I used the Named Parameter Idiom (below note that func2 is not registered for example).
Finally here is the revised code that it works (tested):
-- C++ -- test.h
#include <iostream>
template <typename MODULE> class item;
template <typename MODULE>
class init {
public:
typedef int (MODULE::*funcPtr)(int);
typedef bool (MODULE::*func2Ptr)(bool);
private:
funcPtr m_fp;
func2Ptr m_fp2;
MODULE* m_dad;
public:
init& has_funcPtr(funcPtr fp) { m_fp = fp; return *this;}
init& has_func2Ptr(func2Ptr fp2) { m_fp2 = fp2; return *this;}
init(MODULE* dad) : m_dad(dad) { std::cout << "init constructor called\n"; }
~init() {}
private:
friend class item<MODULE>;
};
template <typename MODULE>
class item {
public:
typedef int (MODULE::*funcPtr)(int);
typedef bool (MODULE::*func2Ptr)(bool);
private:
funcPtr m_fp;
func2Ptr m_fp2;
MODULE* m_dad;
public:
item(init<MODULE> params) :
m_fp(params.m_fp),
m_fp2(params.m_fp2),
m_dad(params.m_dad)
{
std::cout << "item constructor called\n";
}
~item() {}
// Method invoked externally
int callback() {
std::cout << "item class method callback invoked\n";
// In the real case here do general stuff
if(m_fp) {
int i = (m_dad->*m_fp)(1); // call member function through its pointer
return i;
} else {
std::cout << "callback not registered\n";
return 0;
}
}
// Method invoked externally
bool callback2() {
std::cout << "items class method callback2 invoked\n";
// In the real case here do general stuff
if(m_fp2) {
bool b = (m_dad->*m_fp2)(true); // call member function through its pointer
return b;
} else {
std::cout << "callback2 not registered\n";
return false;
}
}
};
class user {
public:
typedef init<user>::funcPtr funcPtr;
private:
// Methods that optionally add more functionalities to the 2 callbacks
int func1(int i);
bool func2(bool b);
public:
// Item member
item<user> m_item;
public:
user();
~user();
};
-- C++ -- test.cpp
#include "test.h"
user::user() : m_item(init<user>(this).has_funcPtr(&user::func1) ) {
std::cout << "user constructor called\n";
}
int user::func1(int i) {return i;}
bool user::func2(bool b) {return b;} // func2 won't be registered
int main() {
user* u = new user();
// Test callbacks
int i = u->m_item.callback();
bool b = u->m_item.callback2();
std::cout << "main is printing i=" << i << " and b=" << b << "\n";
std::cout << "expected results are i=1 and b=0\n" << "END\n";
return 0;
}
OUTPUT:
init constructor called
item constructor called
user constructor called
item class method callback invoked
items class method callback2 invoked
callback2 not registered
main is printing i=1 and b=0
expected results are i=1 and b=0
END

How to create parameterized constructor of a class in another class as a data member?

In below example,
class Car
{
private:
int sides;
public:
Car()
{
cout<<"\ndefault called constructor";
}
Car(int nsides)
{
cout<<"\ncalled constructor";
sides=nsides;
}
};
class Auto
{
private:
Car ch;
public:
Auto(int a) : Car(a)
{
//Car test(5);
}
};
int main()
{
Auto at(5);
return 0;
}
After referring below links :-
create objects in object passing variables through constructor
http://www.cplusplus.com/forum/beginner/9746/
I tried to write the same and execute it.unfortunately I am getting following compiler error :-
check.cpp: In constructor ‘Auto::Auto(int)’:
check.cpp:44: error: type ‘Car’ is not a direct base of ‘Auto’
If solution mentioned in the given links are correct then what wrong in my code ? My next query is ...why only parametrized constructor() throws compiler if try to initialize it without using initialization list.
This will throw compiler error :-
class Auto
{
private:
Car ch(5);
public:
Auto(int a)
{
}
};
But this does not :-
class Auto
{
private:
Car ch;
public:
Auto(int a)
{
}
};
Please help me in understanding this behaviour.
Thanks in advance.
In your example you are specifying by your constructor Auto(int a) : Car(a) that Auto is derived from Car, and that's what the compiler complains about.
To initialize your Car object (inside of Auto), do this Auto(int a) : ch(a). You put the type instead of the member's name.
About your second question, in-class member initialization is a new feature brought by C++11. You may use it by adding the parameter -std=c++11 to your compiler (GCC or Clang, msvc doesn't support it). See this question. In your case you can use it as chris pointed out :
class Auto {
// ...
Car ch{5};
int someVal = 5;
// ...
};

declaration and definition of constructor of class and print out private and public variables?

I am having hard time, I am learning classes in C++ now, here is problem I have, I have to declare and define constructor, i dont know what wrong i am doing i tried but could not get the result please help
#include <iostream>
using namespace std;
class exercise
{
public:
//declaration: constructor of class exercise
int public_var;
int get_private_var();
private:
int private_var;
};
//definition: constructor of class exercise
int exercise::get_private_var()
{
return private_var;
}
int main()
{
exercise object(2,3);
int pub_var = object.public_var;
int pri_var = object.get_private_var();
cout << pub_var <<' '<<pri_var<<endl;
return 0;
}
A sample constructor would be:
class exercise
{
public:
exercise(int,int);
int public_var;
int get_private_var();
private:
int private_var;
};
//Constructor definition
exercise::exercise(int a, int b)
{
public_var = a;
private_var = b
}
//rest of member functions
In order to declare a constructor you should
class exercise
{
public:
//declaration: constructor of class exercise
exercise();
int public_var;
int get_private_var();
private:
int private_var;
};
In order to implement (usually in .cpp file)
you should:
exercise::exercise()
{
//your code here
}
good luck
get_private_var is not a constructor. It's function that is called when you do object.get_private_var() - it's just a typical member function.
The constructor is the function that gets called when you construct your object (makes sense, right?). In your case, it would be used when you do:
exercise object(2,3);
This line constructs an exercise object called object and passed the values 2 and 3 to its constructor. It looks like you want to assign those values to the public_var and private_var members.
First you need to declare your constructor:
class exercise
{
public:
exercise(int, int); //declaration: constructor of class exercise
int public_var;
int get_private_var();
private:
int private_var;
};
As you can see, the constructor is declared just like any other member function, except it does not have a return type. That makes sense since the return type is clearly the class itself. Here I have specified two arguments.
Now we need to define the constructor, similar to how you have defined get_private_var, but again with no return type:
exercise::exercise(int x, int y)
{
public_var = x;
private_var = y;
}
And then you're done. This constructor simply assigns the values that are passed to it to the public and private members.
However, there is a slightly better way of implementing this constructor, using a member initialization list:
exercise::exercise(int x, int y)
: public_var(x), private_var(y)
{ }
Here is how you build a class with constructor
class a
{
public:
int pubvar;
a() //default constructor
{
pubvar =1;
privar =2;
}
a(int one, int two) //constructor with intializing
{
pubvar = one;
privar = two;
}
private:
int privar;
}
now default initialization is
a myclass;
and initialize with your variables is
a myclass(4,2);
hope that helps

c++ redefine a class

I would like to redefine a class in c++ (non clr). Here's the reason
class BabyClass
{
public:
string Name;
int getSiblings(MainClass &mclass)
{
int c = mclass.size();
for(int i=c;i>0;--i)
{
if(mclass.at(i).Name != Name)
cout << mclass.at(i).Name;
}
}
}
class MainClass
{
public:
vector<BabyClass> babies;
}
now of course this isn't my real code, but I think you can see the problem.
I want my baby class to have access to the main class, the problem is at compile time it doesn't know the MainClass exists, so to fix it normally I would put the MainClass above the BabyClass, but if I do that I can't have a vector of BabyClass's because the compiler wouldn't know about the BabyClass.
I know with functions you can do something like
int function(string hello);
then later
int function(string hello)
{
code
}
or use virtual functions and such. Any idea's how I would do this with classes? Thanks.
And by the way, I know someone is going to ask if it's really necessary, so yes, it is.
Try this arrangement which forward declares MainClass.
class MainClass;
class BabyClass
{
public:
string Name;
int getSiblings(MainClass &mclass);
};
class MainClass
{
public:
vector<BabyClass> babies;
};
int BabyClass::getSiblings(MainClass &mclass)
{
// your code which uses mclass
return 0;
}
int main(){}
BTW, this is not called redefine. The technique is to forward declare and then define it.

Several C++ classes need to use the same static method with a different implementation

I need several C++ classes to have a static method "register", however the implementation of register varies between those classes.
It should be static because my idea is to "register" all those classes with Lua (only once of course).
Obviously I can't declare an interface with a static pure virtual function. What do you guys suggest me to do ? Simplicity is welcome, but I think some kind of template could work.
Example of what I would like to achieve
class registerInterface
{
public:
static virtual void register() = 0; //obviously illegal
};
class someClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua
}
}
class someOtherClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua in a different way
}
}
int main()
{
someClass::register();
someOtherClass::register();
return 0;
}
Based on how you've described the problem, it's unclear to me why you even need the 'virtual static method' on the classes. This should be perfectly legal.
class SomeClass {
static void register(void) {
...
}
}
class SomeOtherClass {
static void register(void) {
...
}
}
int main(int argc, char* argv[]) {
SomeClass::register();
SomeOtherClass::register();
return 0;
}
Drop the RegisterInterface, I don't think you need it.
If it helps, you could take Hitesh's answer, and add:
struct luaRegisterManager {
template <typename T>
void registrate() {
T::registrate();
// do something else to record the fact that we've registered -
// perhaps "registrate" should be returning some object to help with that
}
};
Then:
int main() {
luaRegisterManager lrm;
lrm.registrate<someClass>();
lrm.registrate<someOtherClass>();
}
More generally, if you want to introduce any dynamic polymorphism in C++, then you need an object, not just a class. So again, perhaps the various register functions should be returning objects, with some common interface base class registeredClass, or classRegistrationInfo, or something along those lines.
Could provide an example of what you feel it is that you need dynamic polymorphism for? Hitesh's code precisely matches your one example, as far as I can see, so that example must not cover all of your anticipated use cases. If you write the code that would be using it, perhaps it will become clear to you how to implement it, or perhaps someone can advise.
Something else that might help:
#include <iostream>
#include <string>
#include <vector>
struct Registered {
virtual std::string name() = 0;
virtual ~Registered() {}
Registered() {
all.push_back(this);
}
static std::vector<Registered*> all;
};
std::vector<Registered*> Registered::all;
typedef std::vector<Registered*>::iterator Iter;
template <typename T>
struct RegisteredT : Registered {
std::string n;
RegisteredT(const std::string &name) : n(name) { T::registrate(); }
std::string name() { return n; }
// other functions here could be implemented in terms of calls to static
// functions of T.
};
struct someClass {
static Registered *r;
static void registrate() { std::cout << "registering someClass\n"; }
};
Registered *someClass::r = new RegisteredT<someClass>("someClass");
struct someOtherClass {
static Registered *r;
static void registrate() { std::cout << "registering someOtherClass\n"; }
};
Registered *someOtherClass::r = new RegisteredT<someOtherClass>("someOtherClass");
int main() {
for (Iter it = Registered::all.begin(); it < Registered::all.end(); ++it) {
std::cout << (*it)->name() << "\n";
}
}
There are all sorts of problems with this code if you try to split it across multiple compilation units. Furthermore, this kind of thing leads to spurious reports from memory leak detectors unless you also write some code to tear everything down at the end, or use a vector of shared_ptr, Boost pointer vector, etc. But you see the general idea that a class can "register itself", and that you need an object to make virtual calls.
In C++ you usually try to avoid static initialisation, though, in favour of some sort of setup / dependency injection at the start of your program. So normally you would just list all the classes you care about (calling a function on each one) rather than try to do this automatically.
Your intentions are noble, but your solution is inkling towards "overengineering" (unless I am missing an obvious solution).
Here is one possibility: You can use the Virtual Friend function idiom For example,
class RegisterInterface{
friend void register(RegisterInterface* x){x->do_real_register();}
protected:
virtual void do_real_register();
}
class Foo : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
class Bar : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
int main(int argc, char* argv[]) {
BOOST_FOREACH(RegisterInterface* ri, registered_interfaces)
{
register(ri);
}
return 0;
}
I know you've already accepted an answer, but I figured I would write this up anyway. You can have self-registering classes if you use some static initialization and the CRTP:
#include <vector>
#include <iostream>
using namespace std;
class RegisterableRoot // Holds the list of functions to call, doesn't actually need
// need to be a class, could just be a collection of globals
{
public:
typedef void (*registration_func)();
protected:
static std::vector<registration_func> s_registery;
public:
static void do_registration()
{
for(int i = 0; i < s_registery.size(); ++i)
s_registery[i]();
}
static bool add_func(registration_func func) // returns something so we can use it in
// in an initializer
{
s_registery.push_back(func);
return true;
}
};
template<typename RegisterableType> // Doesn't really need to inherit from
class Registerable : public RegisterableRoot // RegisterableRoot
{
protected:
static const bool s_effect;
};
class A : public Registerable<A> // Honestly, neither does A need to inherit from
// Registerable<T>
{
public:
static void Register()
{
cout << "A" << endl;
}
};
class B : public Registerable<B>
{
public:
static void Register()
{
cout << "B" << endl;
}
};
int main()
{
RegisterableRoot::do_registration();
return 0;
}
std::vector<RegisterableRoot::registration_func> RegisterableRoot::s_registery;
template <typename RegisterableType> // This is the "cute" part, we initialize the
// static s_effect so we build the list "magically"
const bool Registerable<RegisterableType>::s_effect = add_func(&RegisterableType::Register);
template class Registerable<A>; // Explicitly instantiate the template
// causes the equivalent of
// s_registery.push_back(&A::Register) to
// be executed
template class Registerable<B>;
This outputs
A
B
although I wouldn't rely on this order if I were you. Note that the template class Registerable<X> need not be in the same translation unit as the call to do_registration, you can put it with the rest of your definition of Foo. If you inherit from Registerable<> and you don't write a static void Register() function for your class you'll get a (admittedly probably cryptic) compiler error much like you might expect if there really was such a thing as "static virtuals". The "magic" merely adds the class specific function to the list to be called, this avoids several of the pitfalls of doing the actual registration in a static initializer. You still have to call do_registration for anything to happen.
How about this way? Define an interface class:
// IFoobar.h
class IFoobar{
public:
virtual void Register(void) = 0;
}
Then define the class that handles the register..
// RegisterFoobar.h
class RegisterFoobar{
public:
// Constructors etc...
IFoobar* fooBar;
static void RegisterFoobar(IFoobar& fubar){
foobar = &fubar;
}
private:
void Raise(void){ foobar->Register(); }
}
Now, then define another class like this
// MyFuBar.h
class MyFuBar : IFoobar{
public:
// Constructors etc...
void Register(void);
private:
RegisterFoobar* _regFoobar;
}
Call the code like this:
//MyFuBar.cpp
MyFuBar::MyFuBar(){
_regFoobar = new Foobar();
_regFoobar->RegisterFoobar(this);
}
void MyFuBar::Register(void){
// Raised here...
}
Maybe I have misunderstood your requirements...