Ok, sorry to bother but it seems I don't understand this properly ^^"

I have a simple class, SLListNode, as follows

template <class D>

class SLListNode {
	public:
	static int Count;
	D Data;
	SLListNode *Next;
	SLListNode(void);
	~SLListNode(void);
};

template <class D>
int SLListNode<D>::Count = 0;

template <class D>
SLListNode<D>::SLListNode(void) {
	Next = NULL;
	Count++;
	if(dbg) {
		cout << endl << "SLListNode of type '" << typeid(D).name() << "' Constructed. Number of SLListNodes of this type now is " \
		<< Count << "." << endl;
	}
	return;
}

template <class D>
SLListNode<D>::~SLListNode(void) {
	Count--;
	if(dbg) {
		cout << endl << "SLListNode of type '" << typeid(D).name() << "' Destructed. Number of SLListNodes of this type now is " \
		<< Count << "." << endl;
	}
	return;
}

and another class I wanted to inherit from SLListNode:

template <class D>
class DLListNode : public SLListNode<D> {
	public:
	DLListNode *Prev;
	DLListNode(void);
	~DLListNode(void);
};

template <class D>
DLListNode<D>::DLListNode(void) {
	Prev = NULL;
	if(dbg) {
		cout << endl << "DLListNode of type '" << typeid(D).name() << "' Constructed. Number of DLListNodes of this type now is " \
		<< Count << "." << endl;
	}
	return;
}

template <class D>
DLListNode<D>::~DLListNode(void) {
	if(dbg) {
		cout << endl << "DLListNode of type '" << typeid(D).name() << "' Destructed. Number of DLListNodes of this type now is " \
		<< Count << "." << endl;
	}
	return;
}

I created an object with: DLListNode<int> ob1; and I thought it would inherit from the base class its own Next pointer, its own Data variable, its "own" static variable Count and that the Base class constructor and destructor were to be called before and after respectively its own.

However, it complains about missing Count in DLListNode class... has a static variable of the base class to be redefined in each derived class?
I had to add static int Count; in the class definition and

template <class D>
int DLListNode<D>::Count = 0;

outside.
And again, the base class constructor (that is called, I see the debug infos printed) does not increment it! Neither does the destructor...
Is the Next pointer initialized at all? I added initialization only to the new Prev pointer - should I reinitialize the first one in the derived class constructor? Evidently I didn't understand how this works.. I will be very grateful if someone does enlighten me a bit :S

Anticipated thanks :)

Recommended Answers

All 4 Replies

A static class variable is like an ordinary global variable but has scope only within the class. Like global variables, there is only one instance of a static variable regardless of the number of instances of the class.

>> it complains about missing Count in DLListNode class...
Because you also have to declare it just like a global variable, but with class scope. Here is a simple example.

#include<iostream>
using namespace std;

class MyClass
{
public:
    MyClass() {x++;}
    ~MyClass() {x--;}
    static int x;
};

int MyClass::x = 0; // <<<<< declare class static variable

int main()
{
    MyClass a;
    cout << a.x << "\n";
    MyClass b;
    cout <<  b.x << "\n";

}
commented: Really helpful and straight to the point. Thank you :) +1

Ok maybe I got this, thank you very much :)
As far as I understood each static variable is not inherited but has to be redeclared in every class scope in which we want it to exist. Fine, that also explains why the Base class constructor/destructor weren't incrementing/decrementing it - in fact they were modifying their own scope version of the variable.
All the rest works as I expected - so far - and I have faced only one more questione while playing around. Consider this example (remaining generic):

class Base {
	public:
	type1 member1;
	type2 member2;
	Base();
	~Base();
};

class Derived : public Base {
	public:
	type3 member3;
	Derived();
	~Derived();
};

int main(void) {
	Base ob1;
	Derived ob2;
	Base *ptrBase;
	ob2.member3 = somedata;
	ptrBase = &ob2; // works fine
	cout << endl << ptrBase->member3 << endl; // error: 'class Base' has no member named 'member3'
	cin.get();
	return EXIT_SUCCESS;
}

It should be clear what I intended to do and where lies the problem. The question is: surely it's a great resource being able to use Base class pointers to point to Derived class objects, but are they really confined to access only the inherited members? I fear that the answer is 'Yes', but maybe I'm not considering some (obvious or less) solution.

Anyway, thanks a lot (again!) for your time and kindness :)

>> ptrBase->member3
That doesn't work because base class knows nothing about the inherited classes. It has to be typecase to the desired class

int main(void) {
	Base ob1;
	Derived ob2;
	Base *ptrBase;
	ob2.member3 = 1;
	ptrBase = &ob2; // works fine
	cout << endl << reinterpret_cast<Derived*>(ptrBase)->member3 << endl;
	cin.get();
	return EXIT_SUCCESS;
}

Really helpful and interesting. I knew nothing about reinterpret_cast :)

Thank you!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.