In this case, there should be only one or zero instances of the static variable. It depends whether f() has been called or not.
void f()
{
static int a;
}
But how many instances of the static variable are there if f() is a method?
class A
{
void f()
{
static int a;
}
};
Same as for the function: 0 or 1. It is very easy to check too:
class A
{
public:
void f()
{
static int a = 0;
++a;
cout << a << endl;
}
};
int main()
{
A a;
a.f();
a.f();
A b;
b.f();
}
Output:
1
2
3
However, if you derieve from class A and make the function virtual like this:
class A
{
public:
virtual void f()
{
static int a = 0;
++a;
cout << a << endl;
}
};
class B:public A
{
public:
void f()
{
static int a = 0;
++a;
cout << a << endl;
}
};
then the a variable will be different for the base and for each derived class (because the functions are different too).
The same... being a member function is orthogonal to being a static local.
Related
#include<iostream>
using namespace std;
class Base {
private: int b;
protected: int a;
public: int c; void setdata(); int getdata(); };
void Base ::setdata() { int a = 10; int b = 20; int c = 30; }
int Base::getdata() { return b; }
class Derived: public Base { public: void display() { setdata(); cout << a << endl << getdata() << endl << c << endl; } };
int main() { Derived xyz; xyz.display(); return 0; }
Lets look at your setdata function:
void Base ::setdata() { int a = 10; int b = 20; int c = 30; }
Inside it you define three new variables a, b and c, which are totally unrelated with the Base member variables of the same name.
That means the Base member variables will be uninitialized and with indeterminate values. And printing them leads to undefined behavior.
Your setdata function should set the Base member variables, which are already declared and defined and can be used as-is:
void Base ::setdata() { a = 10; b = 20; c = 30; }
With that said, a better solution is to use a constructor to initialize the member variables instead of a separate function:
class Base
{
public:
Base()
: a{ 10 }, b{ 20 }, c{ 30 } // An initializer list, to initialize members
{
// Empty body of constructor function
}
// Rest of class, without the setdata function ...
};
I do not understand why the following code does not work since *p is dynamically a B object.
class A {
public:
bool test() {return true;}
};
class B : public A {
public:
bool test() {return false;}
};
int main() {
A* p = new B;
std::cout << p->B::test();
return 0;
}
I know I could use virtual but I believe this is not the point. The compiler says I should define a second constructor or a conversion operator. What can I do ?
*p is dynamically a B object, but with declaration A* p and usage p->test(), A::test() is statically linked at compile time.
If you want dynamic dispatch at runtime, you have to use virtual functions.
#include<iostream>
class A {
public:
bool test() { return true; }
virtual int count() { return 42; }
};
class B : public A {
public:
bool test() { return false; }
virtual int count() { return 100; }
};
int main() {
A* p = new B();
std::cout << p->test() << std::endl; // A::test() is called
std::cout << p->count(); // B::count() is called
}
In the example, functions bool test() will be dispatched statically, while int count() will be dispatched dynamically.
How do I make a static method inaccessible from a derived class?
I have an inheritance of classes of the following type Square
from which rectangle and rhombus are derived. Then from the rectangle and rhombus a parallelogram is derived. Then from the parallelogram the trapezoid is derived.
I read all these objects (square, rectangle, rhombus, parallelogram, trapeze) in an object vector, but in the end I want to show how many of each I have read. I want to do this through static functions for each class.
Here is the code:
class A
{
protected:
static int n;
public:
A();
static void numberA()
{
cout << n;
}
};
int A::n;
A::A(){ n++; }
class B:public A
{
protected:
static int n;
public:
B();
static void numberB()
{
cout << n;
}
};
int B::n;
B::B(){ n++; }
int main()
{
A a;
B b;
A::numberA();
cout << endl;
B::numberB();
return 0;
}
output:
2
1
And I want 1, 1 because it is one object of class A and one of class B.
I also tried to make the inheritance private or protected but for nothing.
The problem is that the constructor of the derived class will call the base class constructor too.
An easy fix could be to decrement the count of the base class in the derived constructor.
#include <iostream>
class A
{
protected:
inline static int n_{}; // Since C++17
public:
A()
{
++n_;
};
static int number()
{
return n_;
}
};
class B : public A
{
protected:
inline static int n_{};
public:
B()
{
++n_;
--A::n_; // Decrease base count
}
static int number()
{
return n_;
}
};
class C : public B
{
protected:
inline static int n_{};
public:
C()
{
++n_;
--B::n_; // Decrease base count
}
static int number()
{
return n_;
}
};
class D : public A
{
protected:
inline static int n_{};
public:
D()
{
++n_;
--A::n_; // Decrease base count
}
static int number()
{
return n_;
}
};
int main()
{
A a;
B b;
C c;
D d;
std::cout << A::number() << '\n' << B::number() << '\n'
<< C::number() << '\n' << D::number() << '\n';
return 0;
}
I need an array of pointers to member functions in a base class like this
class Base {
public:
typedef int(Base::*func)();
func f[3];
Base();
void run();
};
void Base::run()
{
cout << (this->*f[0])() << endl;
cout << (this->*f[1])() << endl;
cout << (this->*f[2])() << endl;
}
The function run() will be the same for all child classes. But pointers in the array f[] will refer to member functions that will be defined in the child classes.
class Child: public Base {
public:
typedef int(Child::*func)();
func f[3];
int A();
int B();
int C();
Child();
};
int Child::A()
{
return 1;
}
int Child::B()
{
return 2;
}
int Child::C()
{
return 3;
}
Child::Child()
{
f[0] = &Child::A;
f[1] = &Child::B;
f[2] = &Child::C;
}
If I run this code in program I get problems
Child x;
x.run();
How to do this?
This works:
class Base {
public:
typedef int(Base::*func)();
func f[3];
virtual int A() { return 0; }
virtual int B() { return 0; }
virtual int C() { return 0; }
Base() {};
void run()
{
cout << (this->*f[0])() << endl;
cout << (this->*f[1])() << endl;
cout << (this->*f[2])() << endl;
}
};
class Child: public Base {
public:
int A() { return 1; }
int B() { return 2; }
int C() { return 3; }
Child()
{
f[0] = &Base::A;
f[1] = &Base::B;
f[2] = &Base::C;
}
};
You're facing two major obstacles here.
One, you never initialize the Base::f but that is what run operates on. You declare a member f in the child class and initialize it in the constructor. The Base classes f is never initialized, and is filled with garbage. When you call run, it tries to use those random values. This is undefined behavior.
Two, int(Base::*)() and int(Child::*)() are two distinct and incompatible types. You look like you want to fill the array with pointers to child functions and call them from the base class.
There are a couple ways to fix this:
You could make run virtual and implement it in the child class to call the functions.
You could put the functions in the base class and make them virtual, so pointers to them will call the derived versions.
You could make an array of std::function objects instead of pointers.
If I have a pure virtual function can it be overriden with a function pointer? Scenario below (I'm aware that it's not 100% syntactically correct):
#include<iostream>
using namespace std;
class A {
public:
virtual void foo() = 0;
};
class B : public A {
public:
B() { foo = &B::caseOne; }
void caseOne() { cout << "Hello One" << endl; }
void caseTwo() { cout << "Hello Two" << endl; }
void (B::*foo)();
void chooseOne() { foo = &B::caseOne; }
void chooseTwo() { foo = &B::caseTwo; }
};
int main() {
B b;
b.(*foo)();
}
EDIT: In case anyone's interested, here's how I accomplished what I wanted to do:
#include<iostream>
using namespace std;
class A {
public:
virtual void foo() = 0;
};
class B : public A {
public:
B() { f = &B::caseOne; }
void caseOne() { cout << "Hello One" << endl; }
void caseTwo() { cout << "Hello Two" << endl; }
void (B::*f)();
void chooseOne() { f = &B::caseOne; }
void chooseTwo() { f = &B::caseTwo; }
void foo() { (this->*f)(); }
};
int main() {
B b;
b.foo();
b.chooseTwo();
b.foo();
}
The output is:
Hello One
Hello Two
No. And you use this wrong. In your code you are trying to assign member-function pointer to function-pointer - it's cannot be compiled.
C++03 standard 10.3/2
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or
indirectly from Base, a member function vf with the same name and same parameter list as Base::vf is
declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides
Base::vf.
As #ForEveR said, your code cannot compile. However, since what you actually need is the ability of switching B's implementation of foo in the runtime, we do have workaround:
#include <iostream>
using namespace std;
class A {
public:
virtual void foo() = 0;
};
class B : public A {
private:
void (B::*_f)();
public:
B() { chooseOne(); }
void caseOne() {
cout << "case one" << endl;
}
void caseTwo() {
cout << "case two" << endl;
}
void chooseOne() { _f = &B::caseOne; }
void chooseTwo() { _f = &B::caseTwo; }
void foo() {
(this->*_f)();
}
};
int main(int argc, const char *argv[])
{
A* b = new B();
b->foo();
((B*)b)->chooseTwo();
b->foo();
return 0;
}
UPDATE:
Just found the OP added his answer in the question, which is almost the same as mine. But I think calling foo through pointer instead of instance object is better, for that can exhibit the effect of polymorphism. Besides, it's better to hide f as a private member function.
I think when compile time, the syntax can NOT be compiled. You should provide an override function with the certain name and same args list.