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.
Related
When trying to implement a class like this
class sample{
int a;
public:
sample(int a = 0){
this->a =a ;
}
void fun(int base = /*the value of a*/){
// some function code
}
};
I want to initialize the argument base of the function fun with the value of a (the data member of the class).
Writing int base = a or int base = this->a doesn't work.
So, I thought I could overload the function this way.
void fun(void){
fun(a);
}
void fun(int base){
// some function code
}
This will actually work, but is there any better/smarter way to do the same thing? Because I have many other functions, I want to implement the same way. And I don't want to overload each of them.
Thanks.
You can make it explicit with std::optional. Before that (or Boost.Optional or whatever), the usual solution would be to sacrifice a magic value that base could never legally take (such as -1 in the other answer).
class sample{
int a_;
public:
sample(int a = 0) : a_(a) {}
void fun(std::optional<int> base = std::nullopt){
if (!base) base = a_;
// some function code
}
};
Or, as Jarod42 suggests, something like
void fun(std::optional<int> base_opt = std::nullopt){
int base = base_opt.value_or(a_);
// some function code
}
NB.
Writing int base = a or int base = this->a doesn't work
Yeah, there is no instance at the point where the function is declared, and that's when the default expression is evaluated.
I was under the impression that private members, when they're inaccessible at the call site, would be prohibited - but that isn't correct. So the expression must be evaluated when the function is declared, with the function's own access and symbol visibility at that point, even though it is executed at the call site.
Sentinel values
This can be achieved via a "sentinel" value. If a particular integer is unused (such as -1), try:
void fun(int base = -1) {
if (base == -1) {
base = this->a;
}
// ...
}
std::optional
Another way is to wrap the input up with an std::optional:
void fun(std::optional<int> base = std::nullopt) {
if (!base) {
base = this->a;
}
// Extract actual value by using *.
int base_value = *base;
// Use base_value.
// ...
}
In the example above, base_value is the "default"-corrected int that you desired. A more elegant alternative is to use std::optional<T>::value_or to extract the value:
void fun(std::optional<int> base = std::nullopt) {
int base_value = base.value_or(this->a);
// Use base_value.
// ...
}
Overload of fun is simple and clean:
class sample{
int a;
public:
sample(int a = 0){
this->a =a ;
}
void fun(){
fun(a);
}
void fun(int base){
// some function code
}
};
I was wondering whether there's a way to override a function for a specific instance only. For ex,
class A
{
public:
...
void update();
...
}
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new A();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new A();
// ....so on.
...
}
Is there a way to achieve this?
I think virtual function is just what you want, with virtual function, different instances of the same type can have different functions, but you need to inherit the base class. for example
class A
{
public:
...
virtual void update()
{
std::cout << "Class A\n";
}
...
};
class B: public A
{
public:
virtual void update()
{
std::cout << "Class B\n";
}
};
class C: public A
{
public:
virtual void update()
{
std::cout << "Class C\n";
}
};
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new B();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new C();
// ....so on.
...
}
each instance in the above code will bind different update functions.
Besides, you can also use function pointer to implement your requirement, but it is not recommended. For example
class A
{
public:
A(void(*u)())
{
this->update = u;
}
...
void (*update)();
};
void a_update()
{
std::cout << "update A\n";
}
void b_update()
{
std::cout << "update B\n";
}
void c_update()
{
std::cout << "update C\n";
}
int main()
{
...
A first_instance(a_update);
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A second_instance(b_update);
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A third_instance(c_update);
// ....so on.
...
}
Hope helps!
Hold a function in the class.
#include <iostream>
#include <functional>
using namespace std;
class Foo
{
public:
Foo(const function<void ()>& f) : func(f)
{
}
void callFunc()
{
func();
}
private:
function<void ()> func;
};
void printFoo() { cout<<"foo"<<endl; }
void printBar() { cout<<"bar"<<endl; }
int main()
{
Foo a(printFoo);
Foo b(printBar);
a.callFunc();
b.callFunc();
}
You may have noticed that the end brace of a class is often followed by a semicolon, whereas the end braces of functions, while loops etc don't. There's a reason for this, which relates to a feature of struct in C. Because a class is almost identical to a struct, this feature exists for C++ classes too.
Basically, a struct in C may declare a named instance instead of (or as well as) a named "type" (scare quotes because a struct type in C isn't a valid type name in itself). A C++ class can therefore do the same thing, though AFAIK there may be severe limitations on what else that class can do.
I'm not in a position to check at the moment, and it's certainly not something I remember using, but that may mean you can declare a named class instance inheriting from a base class without giving it a class name. There will still be a derived type, but it will be anonymous.
If valid at all, it should look something like...
class : public baseclass // note - no derived class name
{
public:
virtual funcname ()
{
...
}
} instancename;
Personally, even if this is valid, I'd avoid using it for a number of reasons. For example, the lack of a class name means that it's not possible to define member functions separately. That means that the whole class declaration and definition must go where you want the instance declared - a lot of clutter to drop in the middle of a function, or even in a list of global variables.
With no class name, there's presumably no way to declare a constructor or destructor. And if you have non-default constructors from the base class, AFAIK there's no way to specify constructor parameters with this.
And as I said, I haven't checked this - that syntax may well be illegal as well as ugly.
Some more practical approaches to varying behaviour per-instance include...
Using dependency injection - e.g. providing a function pointer or class instance (or lambda) for some part of the behavior as a constructor parameter.
Using a template class - effectively compile-time dependency injection, with the dependency provided as a function parameter to the template.
I think it will be the best if you'll tell us why do you need to override a function for a specific instance.
But here's another approach: Strategy pattern.
Your class need a member that represent some behaviour. So you're creating some abstract class that will be an interface for different behaviours, then you'll implement different behaviours in subclasses of that abstract class. So you can choose those behaviours for any object at any time.
class A;//forward declaration
class Updater
{
public:
virtual ~Updater() {};//don't forget about virtual destructor, though it's not needed in this case of class containing only one function
virtual void update(A&) = 0;
}
class SomeUpdater
{
public:
virtual void update(A & a);//concrete realisation of an update() method
}
class A
{
private:
Updater mUpdater;
public:
explicit A(Updater updater);//constructor takes an updater, let's pretend we want to choose a behaviour once for a lifetime of an object - at creation
void update()
{
mUpdater.update(this);
}
}
You can use local classes, yet, personally, I consider the "hold function in the class" approach mentioned in the other answer better. I'd recommend the following approach only if doFunc must access internals of your base class, which is not possible from a function held in a member variable:
class ABase {
public:
void Func () { this->doFunc (); }
private:
virtual void doFunc () = 0;
public:
virtual ~ABase () { }
};
ABase* makeFirstA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "First A"; }
};
return new MyA;
}
ABase* makeSecondA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "Second A"; }
};
return new MyA;
}
int main () {
std::shared_ptr<ABase> first (makeFirstA ());
std::shared_ptr<ABase> second (makeSecondA ());
first->Func ();
second->Func ();
}
From a design patterns point of view, the "local classes" approach implements the template method pattern, while the "hold a function(al) in a member variable" approach reflects the strategy pattern. Which one is more appropriate depends on what you need to achieve.
Can someone explain why the result of the code below would be "class B::1" ?
Why does the virtual method of derived class uses the default parameter of a base class and not his own? For me this is pretty strange. Thanks in advance!
Code:
#include <iostream>
using namespace std;
class A
{
public:
virtual void func(int a = 1)
{
cout << "class A::" << a;
}
};
class B : public A
{
public:
virtual void func(int a = 2)
{
cout << "class B::" << a;
}
};
int main()
{
A * a = new B;
a->func();
return 0;
}
Because default arguments are resolved according to the static type of this (ie, the type of the variable itself, like A& in A& a;).
Modifying your example slightly:
#include <iostream>
class A
{
public:
virtual void func(int a = 1)
{
std::cout << "class A::" << a << "\n";
}
};
class B : public A
{
public:
virtual void func(int a = 2)
{
std::cout << "class B::" << a << "\n";
}
};
void func(A& a) { a.func(); }
int main()
{
B b;
func(b);
b.func();
return 0;
}
We observe the following output:
class B::1
class B::2
In action at ideone.
It is not recommended that a virtual function change the default value for this reason. Unfortunately I don't know any compiler that warns on this construct.
The technical explication is that there are two ways of dealing with default argument:
create a new function to act as trampoline: void A::func() { func(1); }
add-in the missing argument at the call site a.func() => a.func(/*magic*/1)
If it were the former (and assuming that the A::func was declared virtual as well), then it would work like you expect. However the latter form was elected, either because issues with virtual were not foreseen at the time or because they were deemed inconsequential in face of the benefits (if any...).
Because default value is substituted during compilation and is taken from declaration, while real function to be called (A::func or B::func) is determined at runtime.
Because polymorphism in C++ takes effect at run-time, whereas the substitution of default parameters takes effect at compile-time. At compile time, the compiler does not know (and is not supposed to know) the dynamic type of the object to which the pointer a points. Hence, it takes the default argument for the only type it knows for a, which in your example is A *.
(This incidentally is also the reason default parameters are given in interfaces/headers rather than in implementations/definitions. The compiler never inserts the default parameter in the implementation's machine code, but only in the caller's machine code. Technically, the default parameter is the property of the caller; and the caller doesn't know -- and shouldn't need to know -- an object's dynamic type.)
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
When we create an object of a class what does it memory map look like. I am more interested in how the object calls the non virtual member functions. Does the compiler create a table like vtable which is shared between all objects?
class A
{
public:
void f0() {}
int int_in_b1;
};
A * a = new A;
What will be the memory map of a?
You can imagine this code:
struct A {
void f() {}
int int_in_b1;
};
int main() {
A a;
a.f();
return 0;
}
Being transformed into something like:
struct A {
int int_in_b1;
};
void A__f(A* const this) {}
int main() {
A a;
A__f(&a);
return 0;
}
Calling f is straight-forward because it's non-virtual. (And sometimes for virtual calls, the virtual dispatch can be avoided if the dynamic type of the object is known, as it is here.)
A longer example that will either give you an idea about how virtual functions work or terribly confuse you:
struct B {
virtual void foo() { puts(__func__); }
};
struct D : B {
virtual void foo() { puts(__func__); }
};
int main() {
B* a[] = { new B(), new D() };
a[0]->foo();
a[1]->foo();
return 0;
}
Becomes something like:
void B_foo(void) { puts(__func__); }
void D_foo(void) { puts(__func__); }
struct B_VT {
void (*foo)(void);
}
B_vtable = { B_foo },
D_vtable = { D_foo };
typedef struct B {
struct B_VT* vt;
} B;
B* new_B(void) {
B* p = malloc(sizeof(B));
p->vt = &B_vtable;
return p;
}
typedef struct D {
struct B_VT* vt;
} D;
D* new_D(void) {
D* p = malloc(sizeof(D));
p->vt = &D_vtable;
return p;
}
int main() {
B* a[] = {new_B(), new_D()};
a[0]->vt->foo();
a[1]->vt->foo();
return 0;
}
Each object only has one vtable pointer, and you can add many virtual methods to the class without affecting object size. (The vtable grows, but this is stored once per class and is not significant size overhead.) Note that I've simplified many details in this example, but it does work: destructors are not addressed (which should additionally be virtual here), it leaks memory, and the __func__ values will be slightly different (they're generated by the compiler for the current function's name), among others.
Recognize that the C++ language doesn't specify or mandate everything about memory layout for objects. That said, most compilers do it pretty much the same.
In your example, objects of type A require only enough memory to hold an int. Since it has no virtual functions, it needs no vtable. If the f0 member had been declared virtual, then objects of type A would typically start with a pointer to the class A vtable (shared by all objects of type A) followed by the int member.
In turn, the vtable has a pointer to each virtual function, defined, inherited or overridden. Calling a virtual function for an object consists of following the pointer to the vtable from the object, then using a fixed offset into the vtable (determined at compile time for each virtual function) to find the address of the function to call.
functions are not stored based on what class they are in.
usually the compiler will just treat any member function just like any other function except adds an argument for the 'this' pointer. which is automatically passed to the function when you called it based on the address of the object it is called on.
all functions, static, member, or even virtual member are stored in memory in the same way, they are all just functions.
when the compiler builds the code it pretty much hard codes where it goes into memory, then the linker goes through your code and replaces the "call the function with this name" command with "call the function at this hard coded address"
class A
{
public:
void f0() {}
void f1(int x) {int_in_b1 = x; }
int int_in_b1;
};
A *a = new A();
is internally implemented (represented) like this: (function name are actually mangled)
struct A
{
int int_in_b1;
};
void Class_A__constructor(struct a*) {} // default constructor
void Class_A__f0(struct a*) {}
void Class_A__f1(struct a*, int x) {a->int_in_b1 = x;}
// new is translated like this: (inline)
void* new() {
void* addr = malloc(sizeof(struc a));
Class_A__constructor(addr);
return addr;
}
It can be verify by doing a command "nm" on the object file (result with mangled named)