Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 «  : 02-11-2004 11:59 »   | 
								
								 | 
							  
							 
							Есть два виртуальных класса (имена изменены, любое сходство случайно   ) class A{ ... virtual void userproc(int result){}; };
  class B{ ... virtual void userproc(int result){}; };Эти классы что-то вычисляют, и вызывают userproc с результатом вычислений в качестве параметра. потомки классов перекрывают юзерпроки своими полезными процедурами. Теперь появилась нужда в классе class AB:public A,public B{ <виртуальная функция, замещающая A::userproc> <виртуальная функция, замещающая B::userproc> }Это как-нибудь можно реализовать? Что-то я по Страуструпу глазами пробежал - не нашел...    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 16:59 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Pu
							
								Большой босс 
								
								 
								  Offline
								
								78
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #1 : 02-11-2004 12:11 »   | 
								
								 | 
							  
							 
							не очень понял   . может так: class AB:public A,public B {  virtual void userprocA(int result)  {     A::userproc(result);  }  virtual void userprocB(int result)  {    B::userproc(result);  } };
   
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:00 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
							 
							Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #2 : 02-11-2004 13:59 »   | 
								
								 | 
							  
							 
							не очень понял   . может так: class AB:public A,public B {  virtual void userprocA(int result)  {     A::userproc(result);  }  virtual void userprocB(int result)  {    B::userproc(result);  } };
  нет, так не пойдет. Виртуальные функции вызываются из других методов классов A и B. Что-то типа этого: class A{ 	virtual void userproc(int result){}; 	void main(){ 		... 		userproc(15); 	} }И идея в том, что процедура main должна вызывать AB::<виртуальная функция, замещающая A::userproc>  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:01 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Pu
							
								Большой босс 
								
								 
								  Offline
								
								78
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #3 : 02-11-2004 14:22 »   | 
								
								 | 
							  
							 
							Алик, а для какого объекта, А или АВ? Что то я тебя не понял. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							npak
							
						 | 
						
							
								  | 
								
									
									 « Ответ #4 : 02-11-2004 14:28 »   | 
								
								 | 
							  
							 
							Алик, а тебе что надо?  Ты словами объясни, без кода.  Какую цель ты преследуешь, что хочешь решить?
  Может быть тогда найдётся более изящный путь? 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #5 : 02-11-2004 15:12 »   | 
								
								 | 
							  
							 
							Есть класс, который перебирает все возможные комбинации  чисел от 0 до x. Для каждой последовательности вызывается виртуальная процедура void userproc(vector<DWORD>& v) (в векторе - комбинация).  В этом классе она ничего не делает и должна быть перекрыта в потомке (и действовать в зависимости от нужд пользователя). И второй класс действует по такому же принципу. Производный класс использует функциональность обоих классов. Вот. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							npak
							
						 | 
						
							
								  | 
								
									
									 « Ответ #6 : 02-11-2004 15:25 »   | 
								
								 | 
							  
							 
							Алик, что значит "использует" ? Если тебе надо вызывать функции базовых классов, то обращайся к ним как A::userproc и B::userproc Более того, достаточно сделать абстрактный базовый класс и унаследовать A, В и АВ от него. class base_C { public:     virtual void userproc(int x) = 0; };
  class A : public base_C { public:     virtual void userproc(int ); };
  class B : public base_C { public:     virtual void userproc(int ); };
  class C : public base_C {     A _a;     B _b; public:     virtual void userproc(int );          };
  void C::userproc(int x) {     _a.userproc(x);     _b.userproc(x); } 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:02 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
							 
							
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #7 : 03-11-2004 03:12 »   | 
								
								 | 
							  
							 
							npak, в твоем коде уже не множественное наследование (вообще не наследование). Я знаю, что есть этот вариант.  Но мне интересно, дает ли язык возможность осуществить мой замысел именно через множественное наследование, иначе придется объявлять 2 класса, производных от А и B с перекрытым методом userproc, и уже экземпляры этих классов делать членами класса C, что, на мой взгляд, не очень элегантно. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Pu
							
								Большой босс 
								
								 
								  Offline
								
								78
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #8 : 03-11-2004 06:39 »   | 
								
								 | 
							  
							 
							Алик, мдааааааа         :new_shot:  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс 
						 | 
					 
				 
			 |  
		 
	 | 
	| 
		
		
	 | 
	
		
		
			
				
					
						
							lapulya
							
								Молодой специалист 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #10 : 03-11-2004 08:04 »   | 
								
								 | 
							  
							 
							Алик, этой загадочной фразы я просто не понял Есть два виртуальных класса 
  особенно если после этого следует такой код class A{  ...  virtual void userproc(int result){};  }; 
  class B{  ...  virtual void userproc(int result){};  };
  Идем дальше, ты пишешь Теперь появилась нужда в классе  Код: class AB:public A,public B{  <виртуальная функция, замещающая A::userproc>  <виртуальная функция, замещающая B::userproc>  }
  У меня тут вопрос, в класса AB должны быть ДВЕ функции (одна из которых замещаяет A::userproc, а вторая B::userproc) или одна??? вот посмотри сюда может тебе надо это class Abstruct { public: 	virtual ~Abstruct() {} 	virtual void f(const char * s) = 0; };
  class A : public Abstruct { 	public: 	void fa(const char * s) 	{ 		//	... 		f(s); 	} };
  class B : public Abstruct { 	public: 	void fb(const char * s) 	{ 		//	... 		f(s); 	} };
  class AB : public A, public B { 	public: 	void f(const char * s) 	{ 		s = "do something..."; 	} };
  void main() { 	AB ab; 	ab.fa("fa"); 	ab.fb("fb"); }
   
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:03 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
							 
							С уважением Lapulya 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #11 : 03-11-2004 08:23 »   | 
								
								 | 
							  
							 
							Алик, этой загадочной фразы я просто не понял Есть два виртуальных класса 
  особенно если после этого следует такой код class A{  ...  virtual void userproc(int result){};  }; 
  class B{  ...  virtual void userproc(int result){};  };
  Идем дальше, ты пишешь Теперь появилась нужда в классе  Код: class AB:public A,public B{  <виртуальная функция, замещающая A::userproc>  <виртуальная функция, замещающая B::userproc>  }
  У меня тут вопрос, в класса AB должны быть ДВЕ функции (одна из которых замещаяет A::userproc, а вторая B::userproc) или одна??? вот посмотри сюда может тебе надо это class Abstruct { public: 	virtual ~Abstruct() {} 	virtual void f(const char * s) = 0; };
  class A : public Abstruct { 	public: 	void fa(const char * s) 	{ 		//	... 		f(s); 	} };
  class B : public Abstruct { 	public: 	void fb(const char * s) 	{ 		//	... 		f(s); 	} };
  class AB : public A, public B { 	public: 	void f(const char * s) 	{ 		s = "do something..."; 	} };
  void main() { 	AB ab; 	ab.fa("fa"); 	ab.fb("fb"); }
   Виртуальный класс - класс, имеющий виртуальные методы (то есть, имеющий vtbl).  Не путать с виртуальным базовым классом. Что тебе непонятно в моей фразе? Да, мне нужно, чтобы класс потомок имел ДВА метода, каждый из которых перекрывал бы виртуальный метод одного из классов-предков. Единственная загвоздка - эти виртуальные методы имеют одинаковые имена. Как это обойти?  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:04 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Pu
							
								Большой босс 
								
								 
								  Offline
								
								78
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #12 : 03-11-2004 08:26 »   | 
								
								 | 
							  
							 
							lapulya, дело в том что эти функции в А и В НИЧЕГО НЕ ДЕЛАЮТ. Те это просто  virtual void userproc(int result) = 0; как я понимаю,(цитата - " В этом классе она ничего не делает и должна быть перекрыта в потомке") а подменить в потомках я не вижу никакой сложности, хоть трижды наследуй. Посему понял что смысл вопроса - сколько будет дважды два четыре. И ответ соответствующий TRUE.     
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #13 : 03-11-2004 08:37 »   | 
								
								 | 
							  
							 
							Таварищи, ну граждане родненькие! ну где дважды два?? Pu, ну напиши код для примера, если все так просто! 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							lapulya
							
								Молодой специалист 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #14 : 03-11-2004 08:42 »   | 
								
								 | 
							  
							 
							Алик,  Виртуальный класс - класс, имеющий виртуальные методы (то есть, имеющий vtbl). 
 
 Это где же ты такое определение увидал то          ну а вот так  Да, мне нужно, чтобы класс потомок имел ДВА метода, каждый из которых перекрывал бы виртуальный метод одного из классов-предков.  Единственная загвоздка - эти виртуальные методы имеют одинаковые имена. Как это обойти?
 
 сделать нельзя! Pu,  дело в том что эти функции в А и В НИЧЕГО НЕ ДЕЛАЮТ
 
 Дык!!! они и у меня ничего не делают...вот смотри, функция  virtual void f(const char * s) = 0;
 
 объавлена в классе Abstract (это аналог virtual void userproc(int result) = 0; ), а в классе А и В объявление этих функций присутствует только косвенно т.к. они оба наследники австрактного класса Abstract, и естественно ни А ни В не реализуют эту функцию...  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							С уважением Lapulya 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #15 : 03-11-2004 08:54 »   | 
								
								 | 
							  
							 
							Это где же ты такое определение увидал то     Вроде, у Страуструпа где-то. ну а вот так  Да, мне нужно, чтобы класс потомок имел ДВА метода, каждый из которых перекрывал бы виртуальный метод одного из классов-предков.  Единственная загвоздка - эти виртуальные методы имеют одинаковые имена. Как это обойти?   сделать нельзя!  Ну я так и подозревал. Придется изворачиваться... lapulya,Твой пример с классом Abstract делает не то, что мне нужно. Там оба виртуальных метода предков перекрываются одним методом потомка.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Pu
							
								Большой босс 
								
								 
								  Offline
								
								78
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #16 : 03-11-2004 09:14 »   | 
								
								 | 
							  
							 
							Алик, а зачем два метода     . Ты в одной области видимости НИКОГДА не получишь две функции с одной сигнатурой, к бабке не ходи. может повторюсь уж звиняйте class A { public: 	int x; 	A(int v) : x(v) {} 	virtual void f(int i) = 0; // ничего не делает };
  class B { public: 	int x; 	B(int v) : x(v) {} 	virtual void f(int i) = 0; // ничего не делает тоже };
  class AB : public A, public B { public: 	AB( int va, int vb) : A(va), B(vb) {} 	virtual void f(int i) // делает чтото и закрывает (тоесть вообще) функции в базовых классах , и дает доступ к любым их паблик и протект членам 	{ 		i = A::x + B::x; 	} };
 
  int _tmain(int argc, _TCHAR* argv[]) { 	AB ab(2,3); 	ab.f( 44); 	return 0; }
   
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:05 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
							 
							Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #17 : 03-11-2004 09:30 »   | 
								
								 | 
							  
							 
							Pu, Твой пример делает не то, что мне нужно. Там ОБА виртуальных метода предков перекрываются ОДНИМ методом потомка. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							npak
							
						 | 
						
							
								  | 
								
									
									 « Ответ #18 : 03-11-2004 09:36 »   | 
								
								 | 
							  
							 
							Алик,  В С++ есть возможность вызвать метод класса предка. AB ab; ab.A::userproc(1); // Вызов метода предка A ab.B::userproc(2); // Вызов метода предка B
  Правильно ли я понимаю, что ты хочешь, чтобы в выражении ab.B::userproc(1) вызывался не тот метод, который определён для класса B, а некоторый другой, переопределённый? Ответ: так нельзя.  Квалификация имени специально придумана, чтобы обходить перегрузку имён и вызывать метод предка. Теперь о множественном наследовании.  Я не вижу никаких выгод в данном случае.  По-моему, агрегация более уместна.  Возможно, это убеждение сформировалось у меня после Java, но я стараюсь избегать в С++ множественного наследования.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:06 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
							 
							
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #19 : 03-11-2004 09:44 »   | 
								
								 | 
							  
							 
							npak, Я согласен, что множественное наследование нужно стараться обходить. Но в моем случае методы обоих классов-предков (те самые, перегруженные в потомке) используют одни и те же данные, являющиеся членами класса-потомка. И обеспечить к этим данным доступ в случае агрегации паревно. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #20 : 03-11-2004 09:56 »   | 
								
								 | 
							  
							 
							В общем, я эту проблему так решил: class tcombinations{ ... 	virtual void userproc(const vector<DWORD>& v){}; ...
  };
  class tsumitems{ ... 	virtual void userproc(const vector<DWORD>& v){}; ... };
  class tsgsumitems:public tsumitems{ 	void userproc(const vector<DWORD>& v)|si_userproc(v);}; 	virtual void si_userproc(const vector<DWORD>& v){}; };
 
  class tsgcombinations:public tcombinations{         void userproc(const vector<DWORD>& v)|cb_userproc(v);};         virtual void cb_userproc(const vector<DWORD>& v){}; };
  class tsumgroupper:public tsgcombinations,public tsgsumitems{ ... //эти два метода, фактически, перекрывают методы userproc классов tsumitems и tcombinations         void si_userproc(const vector<DWORD>& v){             //ду самфин         };		         void cb_userproc(const vector<DWORD>& v){             //ду самфин элс         }; ... }; 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:08 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							lapulya
							
								Молодой специалист 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #21 : 03-11-2004 09:58 »   | 
								
								 | 
							  
							 
							Алик,  class AB {    friend class A;    friend class B;
     A * a;    B * b; };
  и ни какой парильни...  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:10 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
							 
							С уважением Lapulya 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #22 : 03-11-2004 10:02 »   | 
								
								 | 
							  
							 
							lapulya А доступ к членам AB? 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Pu
							
								Большой босс 
								
								 
								  Offline
								
								78
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #23 : 03-11-2004 10:07 »   | 
								
								 | 
							  
							 
							Алик, мне почему-то каэться, что у тебя проблемы с проектированием классов, чтобы предки использовали данные потомков      . Да они и знать не должны что там у них есть какието производные классы!  Изврат, имхо, и полиморфизм вывернутый наизнанку.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							lapulya
							
								Молодой специалист 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #24 : 03-11-2004 10:09 »   | 
								
								 | 
							  
							 
							Алик, ХАХАХАХАХАХАХАХА!!!!!!!!!!!!!!!!!!!!!!! я вот это  class A { public: 	virtual void f(const char * s)  = 0; 	void fa(const char * s) 	{ 		f(s); 	} };
  class B { public: 	virtual void f(const char * s)  = 0; 	void fb(const char * s) 	{ 		f(s); 	} };
  class AA : public A { public: 	virtual void faa(const char * s) = 0;	 	void f(const char * s) { faa(s); };	 };
  class BB : public B { public: 	virtual void fbb(const char * s) = 0;	 	void f(const char * s) { fbb(s); };	 };
  class AB : public AA, public BB { 	public: 	void faa(const char * s) 	{ 		s = "do something..."; 	}
  	void fbb(const char * s) 	{ 		s = "do something..."; 	} };
  void main() { 	AB ab; 	ab.fa("fa"); 	ab.fb("fb"); }
  написал полтора часа назад .... но потом подумал что это полнейший калл и решил что эта писанина не достойна того чтобы на нее смотреть...  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:11 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
							 
							С уважением Lapulya 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							npak
							
						 | 
						
							
								  | 
								
									
									 « Ответ #25 : 03-11-2004 10:14 »   | 
								
								 | 
							  
							 
							Алик, При множественном наследовании объект включает в себя подобъекты, по одному для каждого класса-предка.  Методы классов-предков используют данные, которые приндлежат к под-объектам!  Они не имеют доступа к данным объекта! Вот тебе пример:  #include <iostream>
  class A {     int _x; public:     virtual void f(int x) { _x = x; std::cout << "Class A: " << x << "\n"; } };
  class B {     int _x; public:     virtual void f(int x) { _x = x; std::cout << "Class B: " << x << "\n"; } };
  class AB : public A, public B { public:     virtual void f(int x) { _x = x; std::cout << "Class C: " << x << "\n"; } }; Он не компилируется, потому что в AB::f не указано, какую переменную _x брать -- из подобъекта класса A или из подобъекта класса B.  Если ты введёшь в класс AB переменную int _x, то методы A::f и B::f её НЕ УВИДЯТ! При вызове ab.A::f будет изменено поле ab.A::_x, при вызове ab.B::f будет изменено поле ab.B::_x, но поле ab._x меняться не будет. По этой причине доступ к состоянию потомка для методов-предков не будет. В языке Eiffel есть фича, названная renaming -- при наследовании можно указать, как назвать метод предка в потомке.  Эта фича позволяет избегать конфликта имён полей и методов при множественном наследовании. В С++ такой фичи нет.  Надо ручками вводить промежуточные классы, в которых переопределяются методы, и множественно наследовать от промежуточных классов.  Пример см. http://cpptips.hyperformix.com/cpptips/rename_virt_mi 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:13 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
							 
							
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							lapulya
							
								Молодой специалист 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #26 : 03-11-2004 10:15 »   | 
								
								 | 
							  
							 
							Алик,  А доступ к членам AB?
  да, если написать так class AB  {    friend class A;     friend class B; 
     A * a;     B * b;  }; 
 
  то у А есть доступ к членам АВ  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:14 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
							 
							С уважением Lapulya 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									«  Ответ #27 : 03-11-2004 10:36 »    | 
								
								 | 
							  
							 
							lapulya,     Только не "class AB : public A, public B ", а "class AB : public AA, public BB" Ну, это извраты за неимением красивого решения... Алик, мне почему-то каэться, что у тебя проблемы с проектированием классов, чтобы предки использовали данные потомков      . Да они и знать не должны что там у них есть какието производные классы!  Изврат, имхо, и полиморфизм вывернутый наизнанку.  В моих классах(-предках) виртуальные функции вызываются для того, чтобы вернуть результат. Конкретнее, один из классов возвращает различные комбинации чисел. И каджую комбинацию надо вернуть пользователю. Можно сделать немеренно большой массив этих комбинаций. А можно возвращать их по одной, что и делается с помощью вызова виртуального метода. Этот виртуальный метод пользует комбинации как ему надо, естественно, используя и другие члены дочернего класса. (надеюсь, никого в ступор не ввел    ) npak В языке Eiffel есть фича, названная renaming -- при наследовании можно указать, как назвать метод предка в потомке. Эта фича позволяет избегать конфликта имён полей и методов при множественном наследовании. В С++ такой фичи нет. Надо ручками вводить промежуточные классы, в которых переопределяются методы, и множественно наследовать от промежуточных классов.
 
 Вот-вот, к такому печальному выводу я и пришел...  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алик
							
								Постоялец 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #28 : 03-11-2004 10:40 »   | 
								
								 | 
							  
							 
							Алик,  А доступ к членам AB?
  да, если написать так class AB  {    friend class A;     friend class B; 
     A * a;     B * b;  }; 
 
  то у А есть доступ к членам АВ  Да, но чтобы метод класса А получил доступ к членам класса AB, ему нужно передать ссылку на этот экземпляр AB, что не есть красиво, а есть то же изврат  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 02-12-2007 17:15 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							lapulya
							
								Молодой специалист 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #29 : 03-11-2004 10:48 »   | 
								
								 | 
							  
							 
							Алик, Да, я уже поправил (и дал полный оригинал того, что было у меня прикинуто на эту тему) И все же это решение далеко от идеала... так что советую как прислушаться к замечанию зайца  Алик, мне почему-то каэться, что у тебя проблемы с проектированием классов
 
 рекомендую перепроектировать этот кусок (так сказать сделать локальный рефакторинг)  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							С уважением Lapulya 
						 | 
					 
				 
			 |  
		 
	 | 
	 |