I'm wondering something in C++.
Admitting the following code:
int bar;
class Foo
{
public:
Foo();
private:
int bar;
};
Inside my class, is there any difference between this->bar and Foo::bar? Are there cases where one is invalid?
Inside class Foo (specifically) there is no difference between the two given that bar is not static.
Foo::bar is called the fully qualified name of the member bar, and this form is useful in scenarios where there may be several types in the hierarchy defining a member with the same name. For example, you would need to write Foo::bar here:
class Foo
{
public: Foo();
protected: int bar;
};
class Baz : public Foo
{
public: Baz();
protected: int bar;
void Test()
{
this->bar = 0; // Baz::bar
Foo::bar = 0; // the only way to refer to Foo::bar
}
};
They do the same thing members.
However, you wont be able to use this-> to distinguish members of the same name in the class hierarchy. You will need to use the ClassName:: version to do that.
For what I have learned fiddling around with C/C++, using the -> on something is mainly for a pointer object, and using :: is used for the classes that are part of a namespace or super class that is the general class of whatever you're including
It also allows you you to reference variable of another class (base class in most cases) with the same name. For me it's obvious from this example, hope it'll helps you.
#include <iostream>
using std::cout;
using std::endl;
class Base {
public:
int bar;
Base() : bar(1){}
};
class Derived : public Base {
public:
int bar;
Derived() : Base(), bar(2) {}
void Test() {
cout << "#1: " << bar << endl; // 2
cout << "#2: " << this->bar << endl; // 2
cout << "#3: " << Base::bar << endl; // 1
cout << "#4: " << this->Base::bar << endl; // 1
cout << "#5: " << this->Derived::bar << endl; // 2
}
};
int main()
{
Derived test;
test.Test();
}
This is because the real data stored in class is like this:
struct {
Base::bar = 1;
Derived::bar = 2; // The same as using bar
}
Related
Let's say we have a class that has a function foo() that counts to 3 and we want from another class to be able to modify this function and after modifying it counts to 3 that was previously declared but also executes the new code too. The function foo() would only be called by class1 and i dont want to use inheritance. The new code that im supposed to add lets say it doesnt have any relationship with class1.
For Example:
#include <iostream>
using namespace std;
class class1 {
public:
class1()
{
}
void foo()
{
for(int i =0;i<2;i++)
{cout << i << endl;}
}
};
class class2 {
public:
class2()
{
}
void foo() override
{
Super::foo();
cout << "Jump from a cliff" << endl;
}
};
int main()
{
class1 c1 = class1();
class2 c2 = class2();
c1.foo();
return 0;
}
Result:
0
1
2
Jump From a cliff
You need an object to call a non-static member function.
If you want to get desired output from class2::foo you can implement it for example like this:
class class2 {
public:
void foo()
{
class1 x;
x.foo();
cout << "Jump from a cliff" << endl;
}
};
Alternatively class1 can have a member of type class1.
Found the solution on Array of function pointers.
I'm trying to replace a function in super class A in order to extend its functionality in B class, but without losing the old definition. So is there any way to force the A::b method to use a new definition from B class? I have experience in Java, so I know it is possible in this language. Expected output is
A::b
B::a
A::a
Current output is
A::b
A::a
#include <iostream>
using namespace std;
class A {
protected:
static void a() {
cout << "A::a" << endl;
}
public:
void b() {
cout << "A::b" << endl;
a();
}
};
class B: public A {
protected:
static void a() {
cout << "B::a" << endl;
A::a();
}
};
int main()
{
B b;
b.b();
return 0;
}
https://godbolt.org/z/dnY5o8WfK
I think you meant to use virtual keyword instead of static as shown below, since static in this context means that there is no implicit this parameter for the non-static member function a.
#include <iostream>
using namespace std;
class A {
protected:
virtual void a() { //note the virtual keyword
cout << "A::a" << endl;
}
public:
void b() {
cout << "A::b" << endl;
a();
}
};
class B: public A {
protected:
virtual void a() {//note the virtual keyword
cout << "B::a" << endl;
A::a();
}
};
int main()
{
B b;
b.b();
return 0;
}
The output of the above program can be seen here:
A::b
B::a
A::a
By using virtual we're making the member function a to be a virtual member funciton.
#include <iostream>
using namespace std;
class A {
};
typedef void (A::*funA)(int);
class B : public A {
public:
void m(int) {std::cout << "mm" << std::endl; }
void n(int) { std::cout << "nn"<<std::endl; }
};
typedef void (B::*funB)(int);
class C : public B {
public:
void g(int) {std::cout << "gg" << std::endl; }
void h(int) { std::cout << "hh"<<std::endl; }
};
typedef void (C::*funC)(int);
int main() {
funB f = static_cast<funB>(&C::m);
A* pa = new A;
(pa->*(static_cast<funA>(f)))(2);
return 0;
}
gcc compile and output "mm".
But why can this work? Class A in fact don't define any function.
It seems the class can use its base class or derived class function by this way, even though it doesn't define them.
Since A doesn't contain the member that f refers to, the behaviour is undefined.
The probable reason why it works anyway is that the function B::m doesn't touch the this pointer, so it doesn't "notice" when it's called on an object of the wrong type. Also, A and B are not polymorphic, so dereferencing the pointer-to-member and calling doesn't require examining any vptr.
Consider this class:
struct Foo {
int bar;
Foo(){}
Foo(int a) {
bar = a;
}
};
Now, I have two ways to access member bar:
Foo foo(1234);
cout << foo.bar << endl;
cout << foo.Foo::bar << endl;
But I don't know what is foo.Foo's kind:
using namespace foo.Foo; //error, because foo.Foo is not a namespace
foo.Foo baz; //error, because foo.Foo is not a class
Please tell me what is foo.Foo.
foo.Foo isn't anything. Foo::bar is the bar member of the Foo class, and foo.Foo::bar is the bar member of the Foo class in the instance foo.
That syntax is generally used if you have name conflicts with multiple inheritance. Consider this example:
struct A{int bar;};
struct B{int bar;};
struct C:A,B{};
Now the following code is ambiguous:
C c;
std::cout << c.bar;
We need to say which bar we want:
C c;
std::cout << c.A::bar;
std::cout << c.B::bar;
It is not (foo.Foo)::bar, it's foo.(Foo::bar) and Foo::bar is bar
This can be usefull in this example :
struct A{
int i;
};
struct B{
int i;
};
class C : public A, B{
};
int main(){
C c;
c.i = 0; // request for member 'i' is ambiguous
}
you should use namespaces A and B to access the data, A::i or B::i
Members of struct are public by default , so you can access memebrs with dot and well as scope resolution (::) operator.So foo.Foo::bar is same as foo.bar.
Firstly, let me apologise for the title, I honestly couldn't think how to word it better.
The example below should make my question a little clearer:
class Foo {
public:
Foo(int x);
};
class Bar : public Foo
{
public:
Bar(int y) : Foo(y);
};
Demonstrates code that would force the Bar constructor to call the Foo constructor with parameter Y. My question is, is there a similar method for inheriting a derived class function to call a base class function?
For example all calls to Bar.Func(); would also automatically call Foo.Func();?
class Foo {
public:
Foo(int x);
void DoIt();
};
class Bar : public Foo
{
public:
Bar(int y) : Foo(y);
void DoIt();
};
void Bar::DoIt()
{
Foo::DoIt();
}
If Foo is intended to be derived from and used polymorphicly, you should declare DoIt as virtual. In addition, you will also want a virtual base class destructor.
Automatically, no. You can use Base::member() to call it, though.
struct foo {
void frob() { std::cout << "foo::frob" << std::endl; }
};
struct bar : foo {
void frob() { foo::frob(); std::cout << "bar::frob" << std::endl; }
};
Any public function declared in Foo is also accessible via Bar (the same function will get called). If you may need to override the function in Bar to alter its behaviour, make it virtual.
This is the code you'll need if you want to 'inherit' the function statements for a function F() from its base. Declare F() virtual in Foo, implement some statements there. Then declare F() in Bar and make a call to Foo::F() at the beginning of the implementation of Bar::F():
class Foo {
public:
Foo(int i) { cout << "Foo(" << i << ") called." << endl; }
virtual void F() { cout << "foo::F() called." << endl; }
virtual ~Foo() {};
};
class Bar : public Foo {
public:
Bar(int i) : Foo(i) { cout << "Bar(" << i << ") called" << endl; }
void F() { Foo::F(); cout << "bar::F() called" << endl; }
};
int main(int argc, char** argv) {
Bar b(3);
b.F();
}
gives
Foo(3) called.
Bar(3) called
foo::F() called.
bar::F() called