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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 26.06.2010, 03:25   #1
Kn793
Форумчанин
 
Регистрация: 20.06.2008
Сообщений: 125
По умолчанию Виртуальные методы

Подскажите, чем отличаются вот эти два примера? А конкретно что творится в их таблицах виртуальных методов.
Пример №1:
Код:
class A {
public:
	virtual void foo();
};

class B : public A {
public:
	void foo();
};
Пример №2
Код:
class A {
public:
	virtual void foo();
};

class B : public A {
public:
	virtual void foo();
};
И вот тут тоже не очень понятно. B:foo() вовсе не виртуально, а в итоге всё-равно выводится "3".
Код:
class A {
public:
	virtual void foo() {
		cout << "1";
	}
	int field;
};

class B : public A {
public:
	void foo() {
		cout << "2";
	}
};

class C : public B {
public:
	virtual void foo() {
		cout << "3";
	}
};

int main() {
	A * pointer = new C();
	pointer->foo();
}
Kn793 вне форума Ответить с цитированием
Старый 26.06.2010, 03:47   #2
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Если перегружаемая функция в базовом классе виртуальная, то она будет виртуальной и в производном. Помечать её виртуальной явно или нет, ничего от этого не изменится

Последний раз редактировалось netrino; 26.06.2010 в 05:35.
netrino вне форума Ответить с цитированием
Старый 26.06.2010, 04:25   #3
capta1n
Форумчанин
 
Аватар для capta1n
 
Регистрация: 06.12.2008
Сообщений: 613
По умолчанию

Код:
#include <iostream>

using namespace std;

class A{
public:
	void print(){
		cout << "A class" << endl;
		cout << "X = " << x << endl;
		return;
	}
	int x;
};

class B : public A{
public:
	void print(){
		cout << "B class" << endl;
		cout << "X = " << x << endl;
		cout << "Y = " << y << endl;
		return;
	}
	int y;
};

void main(){
	A *C = new A();
	B *D = new B();
	C->x=10;
	C->print();
	D->y=7;
	D->x=5;
	D->print();
	//
	C = D;
	C->print();
	cin.get();
	return;
}
спецификатор virtual необходим в базовом классе для того, чтобы в каждом из его производных классов использовался именно метод производного класса. Такая необходимость возникает в случае, если методы имеют одинаковые имена.
Посмотрите пример, который выше, а потом пример, который ниже. Отличаются они только тем, что в нижнем примере в базовом классе есть спецификатор virtual. И он меняет суть дела при "перенастройке" базового класса на производный.
В случае работы классов самих от себя - они будут использовать свои функции, но если базовый класс настроить на класс производный (путем "подмены" указателей, кароче тупо присвоения), то решающую роль играет слово virtual
Посмотрите. После присвоения к указателю класса A указателя класса B, сама реализация указателя осталась неизменной - он до сих пор типа A (об этом говорит, например, количество полей, используемых в классе - в производном их 2, а в базовом их 1, вот и получается, что у нас 1 поле), но попробуйте вызвать функцию print
Если базовый с virtual - то вызовите функцию производного класса, то есть того класса, чей указатель взяли (функция предка как бы "невидима" из производного класса, она как бы "виртуальная", зато прекрасно видима функция производного класса)
Если без virtual - то вновь вызовите функцию базового класса (тут функция базового класса видима, а так как мы есть тип А, то вызовим свой "видимый нами" метод )
Такая реализация позволяет ходить базовому классу по производным, и не переживать о том, что будет вызвана его старая базовая функция, а вызываться будут именно функции потомка, то есть в коем он сейчас находится

Код:
#include <iostream>

using namespace std;

class A{
public:
	virtual void print(){
		cout << "A class" << endl;
		cout << "X = " << x << endl;
		return;
	}
	int x;
};

class B : public A{
public:
	void print(){
		cout << "B class" << endl;
		cout << "X = " << x << endl;
		cout << "Y = " << y << endl;
		return;
	}
	int y;
};

void main(){
	A *C = new A();
	B *D = new B();
	C->x=10;
	C->print();
	D->y=7;
	D->x=5;
	D->print();
	//
	C = D;
	C->print();
	cin.get();
	return;
}

Последний раз редактировалось capta1n; 26.06.2010 в 04:58.
capta1n вне форума Ответить с цитированием
Старый 26.06.2010, 05:14   #4
Kn793
Форумчанин
 
Регистрация: 20.06.2008
Сообщений: 125
По умолчанию

netrino, смущает лишь слово "по-идее"
Kn793 вне форума Ответить с цитированием
Старый 26.06.2010, 05:36   #5
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от Kn793 Посмотреть сообщение
netrino, смущает лишь слово "по-идее"
убрал )).
netrino вне форума Ответить с цитированием
Старый 26.06.2010, 15:08   #6
Kn793
Форумчанин
 
Регистрация: 20.06.2008
Сообщений: 125
По умолчанию

Цитата:
Сообщение от netrino Посмотреть сообщение
убрал )).
Ясно, спасибо.
Kn793 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Виртуальные системы. jojahti Софт 12 27.01.2010 14:54
Виртуальные функции bigory Помощь студентам 2 06.06.2009 22:44
НАСЛЕДОВАНИЕ И ВИРТУАЛЬНЫЕ ФУНКЦИИ С++ ermac52 Помощь студентам 1 05.06.2009 11:03
Полиморфизм и виртуальные методы Викдон Общие вопросы Delphi 1 02.02.2009 04:40
Виртуальные машины! Marsik Софт 17 23.04.2008 20:33