Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.11.2012, 22:45   #1
#include <Markus>
Неистово негодуэ
Пользователь
 
Аватар для #include <Markus>
 
Регистрация: 11.09.2011
Сообщений: 61
По умолчанию Наследование статической переменной

Задача такова: есть базовый класс cBase, которую наследуют да класса: cFirst и cSecond. У классов cFirst и cSecond много объектов, но у каждой своры объектов должна быть одна прееменная, определяющая их количество: int Num.
Внимание, вопрос: как создать отдельные статические переменные Num для классов cFirst и cSecond, но чтобы к ним имел "доступ" cBase?
Я хотел решить этот вопрос так, но, как оказалось, статичная прееменная, объявленная в cBase остается статичной(странно, не правда ли? =) ), и не наследуется.

Код:
class cBase
{
public:
   static int Num;
};


class cFirst : public cBase
{
   void func(void)
   {
      cFirst::Num = 1;
   }
};

int cFirst::Num;


class cSecond : public cBase
{
   void func(void)
   {
      cSecond::Num = 2;
   }
};

int cSecond::Num;

Как результат: прееопределение переменной, и это понятно. Но как мне ухитриться, чтобы Num был объявлен единожды(в идеале), и с ним можно было бы работать в cBase.
Если бы эта прееменная была единственная в моем базовом классе, можно было бы решить проблему, объявив каждую свою переменную в своем классе, и работать с ними, передавая в аргументах, но этих переменных у меня много.

Заранее спасибо за заранние ответы.
Жёстко негодую и тупю на всех.

Последний раз редактировалось ACE Valery; 23.11.2012 в 02:06.
#include <Markus> вне форума Ответить с цитированием
Старый 22.11.2012, 23:32   #2
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Странная постановка. Если есть 6 объектов класса cFirst и 8 объектов класса cSecond, то какое значение должен, по-Вашему, получить cBase, обратившись к Num?
Abstraction вне форума Ответить с цитированием
Старый 22.11.2012, 23:57   #3
#include <Markus>
Неистово негодуэ
Пользователь
 
Аватар для #include <Markus>
 
Регистрация: 11.09.2011
Сообщений: 61
По умолчанию

В том то и дело, мне нужно, чтобы для каждого класса создавалась своя статическая переменная, и я бы так и сделал, но прееменных много, классов тоже, хотел как то наследовать статический элемент, чтобы она была статической не для класса cBace, а для всех классов своя. Не обязательно, чтобы это все работало именно так. Главное, чтобы условие, что я описал, выполнялось.
Жёстко негодую и тупю на всех.
#include <Markus> вне форума Ответить с цитированием
Старый 23.11.2012, 00:33   #4
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
Главное, чтобы условие, что я описал, выполнялось.
Цитата:
как создать отдельные статические переменные Num для классов cFirst и cSecond, но чтобы к ним имел "доступ" cBase?
Публичный статический метод в каждом из классов "вернуть число объектов". Его, естественно, сможет дёргать и cBase. Можно сделать публичной и саму переменную (снаружи класса она будет доступна по полному квалифицированному имени, вроде cFirst::Num), но это посредственная идея.
Обратите внимание, что без специальных мер такая переменная в классе cFirst будет считать количество объектов не только самого класса cFirst, но и всех его наследников.
Abstraction вне форума Ответить с цитированием
Старый 23.11.2012, 08:53   #5
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Статическеми переменными или методами не получится, раз CBase должен получать результаты о своих наследниках. Ума не приложу зачем это надо но это лечится виртуальным методом в CBase классе, который надо переопределить в каждом наследнике.
waleri вне форума Ответить с цитированием
Старый 23.11.2012, 09:16   #6
masax
Форумчанин
 
Регистрация: 01.10.2008
Сообщений: 248
По умолчанию

private const int Num
Контакты
skype, почта: bm@kwax.ru
masax вне форума Ответить с цитированием
Старый 23.11.2012, 11:04   #7
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
Статическеми переменными или методами не получится, раз CBase должен получать результаты о своих наследниках. Ума не приложу зачем это надо но это лечится виртуальным методом в CBase классе, который надо переопределить в каждом наследнике.
Что значит - "не получится"?!
Код:
class cBase{
public:
  static void PrintInfo(void);
};

class cFirst : public cBase {
private:
  static int m_firstNum;
public:
  cFirst(void){m_firstNum++;}
  cFirst(const cFirst& c){m_firstNum++;}
  ~cFirst(){m_firstNum--;}
  static int getNum(void){return m_firstNum;}
};

class cSecond : public cBase {
private:
  static int m_secondNum;
public:
  cSecond(void){m_secondNum++;}
  cSecond(const cSecond& c){m_secondNum++;}
  ~cSecond(){m_secondNum--;}
  static int getNum(void){return m_secondNum;}
};

int cFirst::m_firstNum=0;
int cSecond::m_secondNum=0;

void cBase::PrintInfo(void){
  std::cout << cFirst::getNum() << " " << cSecond::getNum() << std::endl;
}
P.S.
Цитата:
private const int Num
Это что, где и зачем?
Abstraction вне форума Ответить с цитированием
Старый 23.11.2012, 12:55   #8
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

В голову мне приходит только решение с шаблонами. Вспоминаем, что в плюсах для каждого из вариантов шаблонов по сути создаётся отдельный класс, а следовательно и static'и должны создаваться отдельные.
Код:
template <class T>
class Base
{
private:
	static int num;
public:
	Base<T>()
	{
		++num;
	}
	virtual ~Base()
	{
		--num;
	}

	static int getNum()
	{
		return num;
	}
};

template <class T>
int Base<T>::num = 0;
Наследуем от этого класса так:
Код:
class A :
	public Base<A>
{
public:
	A(void);
	virtual ~A(void);
};

class B :
	public Base<B>
{
public:
	B(void);
	virtual ~B(void);
};
Проверяем предположение в VS 2012:
Код:
int _tmain(int argc, _TCHAR* argv[])
{
	A* a[5];
	B* b[10];
	for (int i = 0; i < 5; ++i)
		a[i] = new A();
	for (int i = 0; i < 10; ++i)
		b[i] = new B();

	delete a[1];

	cout << "A: " << A::getNum() << endl;
	cout << "B: " << B::getNum() << endl;
	int x = 0;
	cin >> x;

	return 0;
}
Вроде бы работает, но я не совсем уверен в наличии тут UB (неопределенного поведения)

Последний раз редактировалось pu4koff; 23.11.2012 в 14:01.
pu4koff вне форума Ответить с цитированием
Старый 23.11.2012, 15:28   #9
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

А теперь внимание вопрос - где здесь CBase и как он получает доступк этим данным? Вы бы просто сказали, что вам нужен счетчик объектов каждого типа, а то формулировочка у вас... а кстати, если мы унаследуем A или B то результат уже будет несколько не тот.
waleri вне форума Ответить с цитированием
Старый 23.11.2012, 15:33   #10
masax
Форумчанин
 
Регистрация: 01.10.2008
Сообщений: 248
По умолчанию

какое практическое применение сей задачи?
Контакты
skype, почта: bm@kwax.ru
masax вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с взаимодействием динамической и статической памяти - обращение к статической переменной Comst95 Паскаль, Turbo Pascal, PascalABC.NET 1 03.01.2012 18:46
адрес статической переменной EUGY Общие вопросы C/C++ 10 16.08.2011 23:14
Ресурсы в статической библиотеке. EUGY Общие вопросы C/C++ 0 09.07.2011 17:35
Списки в статической памяти. *Натали* Помощь студентам 5 14.04.2010 11:48
объем статической памяти Juffin Общие вопросы Delphi 1 10.11.2009 16:07