C++: Default values in class member - c++

I have a problem with specifying the default values for my C++ class members. My code is:
From Someclass.h:
class SomeClass
{
public:
SomeClass();
~SomeClass();
void printOut (bool);
}
...from SomeClass.cpp:
void SomeClass::printOut(bool foobar=true)
{
if (foobar) { std::cout << foobar << std::endl; }
}
...and finally, from main.cpp:
int main()
{
SomeClass s;
s.printOut();
return 0;
}
This however gives error message (gcc):
../main.cpp: In function `int main()':
../main.cpp:8: error: no matching function for call to `SomeClass::printOut()'
../SomeClass.h:18: note: candidates are: void SomeClass::printOut(bool)
subdir.mk:21: recipe for target `main.o' failed
make: *** [main.o] Error 1
I have tried specifying the default value directly into the class declaration in the header file, etc. I also tried searching both Stack Overflow and Google in general, but cannot find any solution anywhere. What am I doing wrong?

You haven't specified the default value for the parameter in the header as such, the compiler is looking for a function of signature void printOut(void) for your statement s.printOut(); but correctly not finding it. What you need is:
class SomeClass
{
public:
SomeClass();
~SomeClass();
void printOut( bool fValue = true ); // Note change in param in definition
}
And in your cpp :
void SomeClass::printOut(bool foobar /*=true*/ )
{
if (foobar) { std::cout << foobar << std::endl; }
}
As a side note, bear in mind you don't have to put the commented out default value for the parameter in the implementation file but it is a good idea for readability.

You need to declare the default value inside the class definition, not in the implementation.
class SomeClass
{
public:
SomeClass();
~SomeClass();
void printOut (bool foobar = true); //move default here
}
void SomeClass::printOut(bool foobar) //remove from here
{
if (foobar) { std::cout << foobar << std::endl; }
}
Also, note that:
SomeClass s();
doesn't do what you expect it to do. It doesn't create an object s of type SomeClass, but declares a function s with return type SomeClass. s.printOut(); shouldn't compile.
You probably want:
SomeClass s;

Default value must be specified in the declaration of the method, not in the implementation.

Default parameters must be defined in the header like this:
class SomeClass
{
public:
SomeClass();
~SomeClass();
void printOut (bool value = true);
}

rewrite as follow .. note bool b=false
class SomeClass
{
public:
SomeClass();
~SomeClass();
void printOut (bool b=false);
}

Try to specify default value in header file:
class SomeClass
{
public:
SomeClass();
~SomeClass();
void printOut (bool foobar=true);
}

the default value has to be specified in the declaration and not in the definition. You can specify default value at both the places but cant omit from definition. hope i dint confuse you. I will show the e\corrected code so you can understand:
class SomeClass
{
public:
SomeClass();
~SomeClass();
void printOut (bool foobar = true);
}
...from SomeClass.cpp:
void SomeClass::printOut() //or you can use: void SomeClass::printOut(bool foobar=true)
{
if (foobar) { std::cout << foobar << std::endl; }
}
...and finally, from main.cpp:
int main()
{
SomeClass s();
s.printOut();
return 0;
}

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

Passing member function to another object's member function C++

I am having issues trying to pass a function as an argument in another object's function. I am well aware there are many similar topics but I either can't get their solution to work or can't understand them.
class foo
{
public:
void func1(void (*Drawing)(void));
template<class T>
void func2(void (T::*Drawing)(void));
};
class bar
{
private:
foo myFoo;
void Drawing();
void func3() {
// Attempt 1
myFoo.func1(Drawing);
// Attempt 2
myFoo.func2<bar>(&bar::Drawing);
}
};
So in my first attempt, I get the error where you can't convert void (bar::*)(void) to void (*)(void) of which I then found out there are normal function pointers and member function pointers.
Attempt 2 was my feeble attempt to overcome this but I get unresolved externals now...
So how can I successfully pass my Drawing() member function into another function from another object?
The issue is that you cannot consider bar::Drawing as a void (*)(void) function since it's a non static method, which therefore required an object (the this context which will be used)
A solution, assuming c++11 is ok for you, would be to use std::bind and to sligtly modify your foo definition:
class foo
{
public:
void func1(std::function<void(void)> Drawing)
{
Drawing(); // or do whatever you want with it
}
};
Then you will be able to do
void bar::func3() {
myFoo.func1(std::bind(&bar::Drawing, this));
}
making valid a lot of potential uses
int main()
{
bar myBar;
myBar.func3();
foo myFoo;
myFoo.func1([](){ printf("test\n"); });
return 0;
}
I'm guessing you've left out important details as to what you're trying to accomplish. However, the following should give you some idea of what you need to do.
Code
#include <iostream>
class foo
{
public:
void func1(void (*Drawing)(void))
{
std::cout << "func1\n";
}
template<class T>
void func2(T* instance, void (T::*fn)(void))
{
std::cout << "func2: ";
(instance->*fn)();
}
};
class bar
{
public:
bar()
{
func3();
}
private:
foo myFoo;
void Drawing()
{
std::cout << "bar::Drawing()\n";
}
void func3()
{
// Attempt 1
//myFoo.func1(Drawing); // This won't work
// Attempt 2
myFoo.func2(this, &bar::Drawing); // Must pass an object instance if you plan to use the member function
}
};
int main(int argc, char *argv[])
{
bar b;
return 0;
}
Sample Output
func2: bar::Drawing()

C++ Default Constructor Not Found

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){}
};

The use case of 'this' pointer in C++

I understand the meaning of 'this', but I can't see the use case of it.
For the following example, I should teach the compiler if the parameter is the same as member variable, and I need this pointer.
#include <iostream>
using namespace std;
class AAA {
int x;
public:
int hello(int x) { this->x = x;}
int hello2(int y) {x = y;} // same as this->x = y
int getx() {return x;}
};
int main()
{
AAA a;
a.hello(10); // x <- 10
cout << a.getx();
a.hello2(20); // x <- 20
cout << a.getx();
}
What would be the use case for 'this' pointer other than this (contrived) example?
Added
Thanks for all the answers. Even though I make orangeoctopus' answer as accepted one, it's just because he got the most vote. I must say that all the answers are pretty useful, and give me better understanding.
Sometimes you want to return yourself from an operator, such as operator=
MyClass& operator=(const MyClass &rhs) {
// assign rhs into myself
return *this;
}
The 'this' pointer is useful if a method of the class needs to pass the instance (this) to another function.
It's useful if you need to pass a pointer to the current object to another function, or return it. The latter is used to allow stringing functions together:
Obj* Obj::addProperty(std::string str) {
// do stuff
return this;
}
obj->addProperty("foo")->addProperty("bar")->addProperty("baz");
In C++ it is not used very often. However, a very common use is for example in Qt, where you create a widget which has the current object as parent. For example, a window creates a button as its child:
QButton *button = new QButton(this);
When passing a reference to an object within one of its methods. For instance:
struct Event
{
EventProducer* source;
};
class SomeContrivedClass : public EventProducer
{
public:
void CreateEvent()
{
Event event;
event.source = this;
EventManager.ProcessEvent(event);
}
};
Besides obtaining a pointer to your own object to pass (or return) to other functions, and resolving that an identifier is a member even if it is hidden by a local variable, there is an really contrived usage to this in template programming. That use is converting a non-dependent name into a dependent name. Templates are verified in two passes, first before actual type substitution and then again after the type substitution.
If you declare a template class that derives from one of its type parameters you need to qualify access to the base class members so that the compiler bypasses the verification in the first pass and leaves the check for the second pass:
template <typename T>
struct test : T {
void f() {
// print(); // 1st pass Error, print is undefined
this->print(); // 1st pass Ok, print is dependent on T
}
};
struct printer {
void print() { std::cout << "print"; }
};
struct painter {
void paint() { std::cout << "paint"; }
};
int main() {
test<printer> t; // Instantiation, 2nd pass verifies that test<printer>::print is callable
t.f();
//test<painter> ouch; // 2nd pass error, test<painter>::print does not exist
}
The important bit is that since test inherits from T all references to this are dependent on the template argument T and as such the compiler assumes that it is correct and leaves the actual verification to the second stage. There are other solutions, like actually qualifying with the type that implements the method, as in:
template <typename T>
struct test2 : T {
void f() {
T::print(); // 1st pass Ok, print is dependent on T
}
};
But this can have the unwanted side effect that the compiler will statically dispatch the call to printer::print regardless of whether printer is a virtual method or not. So with printer::print being declared virtual, if a class derives from test<print> and implements print then that final overrider will be called, while if the same class derived from test2<print> the code would call printer::print.
// assumes printer::print is virtual
struct most_derived1 : test<printer> {
void print() { std::cout << "most derived"; }
};
struct most_derived2 : test2<printer> {
void print() { std::cout << "most derived"; }
};
int main() {
most_derived1 d1;
d1.f(); // "most derived"
most_derived2 d2;
d2.f(); // "print"
}
You can delete a dynamically created object by calling delete this from one of its member functions.
The this pointer is the pointer to the object itself. Consider for example the following method:
class AAA {
int x;
public:
int hello(int x) { some_method(this, x);}
};
void somefunc(AAA* a_p)
{
......
}
class AAA {
int x;
public:
int hello(int x) { this->x = x;}
int hello2(int y) {x = y;} // same as this.x = y
int getx() {return x;}
void DoSomething() { somefunc(this); }
};
this is implicit whenever you use a member function or variable without specifying it. Other than that, there are many, many situations in which you'll want to pass the current object to another function, or as a return value.
So, yeah, it's quite useful.
Sometimes you need to refer to "this" object itself, and sometimes you may need to disambiguate in cases where a local variable or a function parameter shadows a class member:
class Foo {
int i;
Foo* f() {
return this; // return the 'this' pointer
}
void g(){
j(this); // pass the 'this' pointer to some function j
}
void h(int i) {
this->i = i; // need to distinguish between class member 'i' and function parameter 'i'
}
};
The two first cases (f() and g() are the most meaningful cases. The third one could be avoided just by renaming the class member variable, but there's no way around using this in the first two cases.
Another possible use case of this:
#include <iostream>
using namespace std;
class A
{
public:
void foo()
{
cout << "foo() of A\n";
}
};
class B : A
{
public:
void foo()
{
((A *)this)->foo(); // Same as A::foo();
cout << "foo() of B\n";
}
};
int main()
{
B b;
b.foo();
return 0;
}
g++ this.cpp -o this
./this
foo() of A
foo() of B
One more use of this is to prevent crashes if a method is called on a method is called on a NULL pointer (similar to the NULL object pattern):
class Foo
{
public:
void Fn()
{
if (!this)
return;
...
}
};
...
void UseFoo(Foo* something)
{
something->Fn(); // will not crash if Foo == NULL
}
If this is useful or not depends on the context, but I've seen it occasionally and used it myself, too.
self-assignment protection

C++ ...when all the arguments have default values

I guess that this is a very absurd/basic question, but still:
class m
{
public:
void f(int ***);
/***/
}
void m::f(int ***a = NULL)
{
/***/
}
The call to f (as well as any function which has default values for all the arguments) doesn't accept 0 arguments. Why? How should I format the declaration then?
That works fine if the function definition is in the header file. The rule is that whoever is calling the function has to 'see' the default value.
So, I'm guessing you have the function definition in a separate source file. Assuming that's the case, just put the default in the function declaration (in the class):
class m
{
public:
void f(int *** = 0);
/***/
};
You'll also need to remove the default value from the function definition as you can only define the default in a single place (even if the value itself is the same).
This will work:
class m
{
public:
void f(int ***a = NULL);
};
void m::f(int ***a)
{
}
Default values in C++ are syntactic sugar; the compiler essentially inserts the argument for you at the callsite. This means that the compiler needs to know what the default value is, so it must be supplied by the function declaration.
This also means that if you have inheritance and virtual methods, the default values used are the ones from the static type (i.e., what type the compiler thinks the object is), not from the runtime type. For example:
class Base
{
public:
virtual ~Base() { }
virtual std::string foo(std::string s = "b") { return "Base:" + s; }
};
class Derived
: public Base
{
public:
virtual std::string foo(std::string s = "d") { return "Derived:" + s; }
};
int main(void)
{
Derived d;
Base& b = d;
std::cout << b.foo() << std::endl;
return 0;
}
will print Derived:b, not Derived:d.