Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Множественное наследование, виртуальные функции

Ответить
Настройки темы
C/C++ - Множественное наследование, виртуальные функции

Новый участник


Сообщения: 1
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изменения
Автор: Drongo
Дата: 05-12-2011
Описание: Используйте тег [code] - #
Помогите пожалуйста разобраться...

1. В классах есть переопределенные виртуальные функции класса base. Как сделать так, что бы я мог вызывать эти функции. Например вызвать их из класса name, а не только из publication.

Код: Выделить весь код
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <fstream>
#include <string.h>
using namespace std;
#define  SIZE 256

class base {
public:	
	virtual void print()=0;	
	virtual void out_file()=0;
};
//-------------------------------------------------------
class name: public base {
public:
	char *strname;

	name(char *sname) {
		strname=new char[256];
		strname=sname;
	}

	~name() {
		cout<<" 'имя' уничтожили"<<endl;
	}
	
	void print() {
		cout<<"Название публикации: "<<strname<<endl;
    
	}
	
	void out_file() {
		ofstream stream("result.txt", ios::out | ios::app);
			stream<<strname<<" ";
			stream.close();
	}
};
//-------------------------------------------------------
class type: public base {
public:
	char *strtype;

	type(char *stype) {
		strtype=new char[256];
		strtype=stype;
	}

	~type() {
		cout<<" 'тип' уничтожен "<<endl;
	}
	
	void print() {
		cout<<"Тип публикации: "<<strtype<<endl;
    
	}
	
	void out_file() {
		ofstream stream("result.txt", ios::out | ios::app);
			stream<<strtype<<" ";
			stream.close();
	}
};

//-------------------------------------------------------

class publication: public name, public type
{
	public:

	char *p_name, *p_type;
	int p_np, p_freq, p_nc;
	double p_yc;

	publication(char *name, char *type, int numofpages, int freq, int numofcopies):name(name),type(type)
	{
		p_name=new char[256];
		p_name=name;
		p_type=new char[256];
		p_type=type;
		p_np=numofpages;
		p_freq=freq;
		p_nc=numofcopies;
		cout<<"Объект 'публикация' создан всё гут"<<endl<<"------------------------"<<endl;
	}

	~publication() {
		cout<<" 'публикации' стерлись "<<endl;
	}

	void print(){
		cout<<"Название публикации '"<<p_name<<"' "<<endl;
		cout<<"Тип публикации '"<<p_type<<"'"<<endl;
		cout<<"Кол-во страниц: "<<p_np<<endl;
		cout<<"Частота выпуска: каждые "<<p_freq<<" дней(я)"<<endl;
		cout<<"Тираж: "<<p_nc<<endl;
		cout<<"Копий в год: "<<p_yc<<endl<<"------------------------"<<endl;
	}

	void out_file() {
		ofstream stream("publications.txt", ios::out | ios::app);
			stream<<"Название публикации '"<<p_name<<"' "<<endl;
			stream<<"Тип публикации '"<<p_type<<"'"<<endl;
			stream<<"Кол-во страниц: "<<p_np<<endl;
			stream<<"Частота выпуска: каждые "<<p_freq<<" дней(я)"<<endl;
			stream<<"Тираж: "<<p_nc<<endl;
			stream<<"Копий в год: "<<p_yc<<endl<<endl;
			stream.close();
	}

	friend void Run(publication *);

};
void run (publication *p){
	p->p_yc=(365/(p->p_freq))*(p->p_nc);
}
//---------------------------------------------
void main (void)
{ 
	setlocale(0, "rus");
	int numofpages, freq, numofcopies;
	char *name, *type;
	name=new char[256];
	type=new char[256];
	cout<<"Введите название: "<<endl;
	cin>>name;
	cout<<"Введите тип: "<<endl;
	cin>>type;

	try{
	cout<<"Введите кол-во страниц: "<<endl;
	cin>>numofpages;
	if(numofpages<0) throw 1;
	}
	
	catch(...) {
	    cout<<"Ошибка!Нужно вводить номер!\n";
		ofstream stream("publications.txt", ios::out | ios::app);
		stream<<"Ошибка"<<endl<<endl;
		exit(0);
		
	}

	cout<<"Введите частоту выпуска: "<<endl;
	cin>>freq;
	cout<<"Введите тираж: "<<endl;
	cin>>numofcopies;

	

	publication pubobj(name,type,numofpages,freq,numofcopies); 
	run(&pubobj);
	pubobj.print();
	pubobj.out_file();
	

	getch();
}

Отправлено: 19:55, 05-12-2011

 

ИО Капитана Очевидности


Contributor


Сообщения: 5387
Благодарности: 1105

Профиль | Отправить PM | Цитировать


Если рассудок и жизнь дороги вам, держитесь подальше от указателей на char и никогда не используйте их для работы со строковыми значениями

Цитата:
name(char *sname) {
strname=new char[256];
strname=sname;
}
Вы думаете, что ваша программа копирует строку, переданную в метод класса через параметр, в поле класса, для которого выделили область памяти?
Нет. Ваша программа
1. Выделяет область памяти и сохраняет адрес этой области в значении указателя strname, который является полем класса
2. Заменяет адрес в указателе strname адресом из указателя sname

Таким образом указатели strname и sname содержат адрес одного и того же массива символов. Таким образом "изменяя строку strname" вы изменяете и "строку sname".
А почему? Да потому что это - не строки, а указатели, говорящие "объект находится там".
Более того, при этом область памяти, выделенная командой "strname=new char[256]", безвозвратно теряется, поскольку нет ни одного указателя, хранящего её адрес. Эту память нельзя будет освободить иначе, как прекратив выполнение программы.
Работа со строковыми значениями через указатели на символы производится через специальные функции, и это - крайне сложная задача, требующая тщательнейшего понимания сути выполняемых действий и строжайшего самоконтроля.
Посему для работы со строками можно использовать только классы строковых контейнеров - string, AnsiString и т.д. А char* - только там, где это действительно требуется для достижения максимальной производительности вычислений.

-------
Самое совершенное оружие, которым забиты арсеналы богатых и процветающих наций, может легко уничтожить необразованного, больного, бедного и голодного. Но оно не может уничтожить невежество, болезнь, нищету и голод. (Фидель Кастро)

Почему всех осужденных за измену Родине при Сталине реабилитировали при Горбачёве по отсутствию состава преступления? Потому что при Горбачёве измену Родине перестали считать преступлением.

Это сообщение посчитали полезным следующие участники:

Отправлено: 05:04, 15-12-2011 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


ИО Капитана Очевидности


Contributor


Сообщения: 5387
Благодарности: 1105

Профиль | Отправить PM | Цитировать


Теперь вернусь к основному вопросу
Цитата Alexanderkrup:
В классах есть переопределенные виртуальные функции класса base. Как сделать так, что бы я мог вызывать эти функции. Например вызвать их из класса name, а не только из publication. »
Суть виртуальных функций и заключается в том, что при обращении к методу на любом из уровней многоуровнего класса, будет вызвана реализация самого "верхнего" класса для данного объекта.
Таким образом имена "виртуальных" методов можно спокойно использовать в любом классе, в котором этот метод уже определён (пусть даже "абстрактно").

И нет разницы, производится ли вызов из другого метода данного класса (командой this->VM(); ) или же извне по указателю базового класса (командой TBaseClass->VM(); ). В обоих случаях механизм виртуальных функций определит настоящий класс данного объекта и вызовет соответствующую реализацию для данного уровня.

P.S.
Для того, чтобы вызвать конкретную реализацию виртуальной функции из базового класса (например, чтобы выполнить все реализации по цепочке), нужно написать команду так TBaseClass:VM();

-------
Самое совершенное оружие, которым забиты арсеналы богатых и процветающих наций, может легко уничтожить необразованного, больного, бедного и голодного. Но оно не может уничтожить невежество, болезнь, нищету и голод. (Фидель Кастро)

Почему всех осужденных за измену Родине при Сталине реабилитировали при Горбачёве по отсутствию состава преступления? Потому что при Горбачёве измену Родине перестали считать преступлением.

Это сообщение посчитали полезным следующие участники:

Отправлено: 05:28, 15-12-2011 | #3



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Множественное наследование, виртуальные функции

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
2008 R2 - наследование прав в AD AntiZero Windows Server 2008/2008 R2 1 02-02-2011 20:47
Сбивается наследование безопасности SanyaJoker Microsoft Windows NT/2000/2003 3 27-03-2009 16:06
Прочее - Множественное подключение zayaz Сетевые технологии 2 03-12-2007 11:10
Нужно ли множественное наследование? Crew Программирование и базы данных 8 05-12-2003 05:38
Наследование интерфейсов netmax Программирование и базы данных 2 02-09-2003 20:08




 
Переход