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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 27.08.2011, 05:13   #11
Сtrl
C++
Форумчанин
 
Аватар для Сtrl
 
Регистрация: 27.03.2011
Сообщений: 803
По умолчанию

Цитата:
Во-первых не три, а две.
Три. Или наследование предпочитаете приватное?
Цитата:
Использование struct в данном случаи неправильно
По каким соображениям?
Ищете информацию по C++?
cplusplus.com
Сtrl вне форума Ответить с цитированием
Старый 27.08.2011, 14:25   #12
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Цитата:
По каким соображениям?
Религиозным
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 27.08.2011, 19:13   #13
Zorgan
Пользователь
 
Аватар для Zorgan
 
Регистрация: 26.08.2011
Сообщений: 16
По умолчанию

народ поясните как вы это используете не пайму ?

f->Draw(); // Указатели друг другу равны, но для f будет вызвана другая функция, чем для c это как ?

Последний раз редактировалось Stilet; 28.08.2011 в 11:00.
Zorgan вне форума Ответить с цитированием
Старый 27.08.2011, 19:33   #14
Ivan_32
somewhere else
Участник клуба
 
Аватар для Ivan_32
 
Регистрация: 17.07.2008
Сообщений: 1,409
По умолчанию

Да очень просто используем:
Код:
#include <iostream>

/* Класс-интерфейс для работы с данными */
class IData {
public:
    /* Это абстрактный метод, его нельзя вызвать, т.к. его тело равно нулю
       такие методы нужны для определения интерфейсов, что бы обеспечить невозможность вызова
       метода для базового класса. Класс имеющий абстрактные методы так же называется абстрактным
       то есть предназначенным сугубо для наследования другими классами.
       Абстрактный класс без полей(данных-членов) обычно называют интерфейсом.
    */
    virtual void Display() const = 0;
    /* Виртуальный деструктор обеспечит вызов соответствующего деструктора, основываясь на класса конкретного объекта */
    virtual ~IData() {
        std::cout << "IData destructor" << std::endl;
    }
};

/* Класс целочисленных данных, наследует методы и поля класса IData
   и переопредялет их для задания собственного уникального поведения. */
class IntegerData : public IData {
    int value;
public:
    /* value = _value */
    IntegerData(int _value) : value(_value) {}
    /* Переопределение пронаследованного метода IData::Display */
    void Display() const {
        std::cout << "Integer value is: " << value << std::endl;
    }
    ~IntegerData() {
        std::cout << "IntegerData destructor" << std::endl;
    }
};

/* Класс текстовых данных, наследует методы и поля класса IData
   и переопредялет их для задания собственного уникального поведения. */
class StringData : public IData {
    std::string value;
public:
    /* value = _value */
    StringData(std::string _value) : value(_value) {}
    /* Переопределение пронаследованного метода IData::Display */
    void Display() const {
        std::cout << "String value is: " << value << std::endl;
    }
    ~StringData() {
       std::cout << "StringData destructor" << std::endl;
    }
};

int main(int argc, char *argv[])
{
    /* Создаем сам массив для хранения разнотипных данных */
    IData* array[2];
    /* В реальных приложениях такой массив заполняется на основе входных данных */
    array[0] = new StringData("Hello, World!");
    array[1] = new IntegerData(0x20);
    /* А вот тут и начинается полиморфизм. Программа, основываясь на данных
       о типе конкретно взятого объекта вызывает нужную версию метода Display. При желании, можно вручную указать
       какую именно версию вызвать, просто написав что-то вроде array[i]->IData::Display(),
       и вместо Display из дочернего класса будет вызвана Display из класса IData */
    for(int i = 0; i < 2; i++)
        array[i]->Display();
    /* Здесь программа просто вызовет для каждого объекта его версию деструктора + деструкторы всех базовых классов
       в данном случае только деструктор класса IData */
    for(int i = 0; i < 2; i++)
        delete array[i];
    return 0;
}
Бывают ситуации( и очень часто) когда нужно сделать массив из разных типов значений. Например большая часть оконных систем созданных на основе ООП в С++, так или иначе имеют один базовый класс, какой-нибудь Widget от которого наследуются все дочерние классы окон и контролов( кнопки, слайдеры, текстбоксы итд.итп. ).
"Тяжело в учении, легко в бою" - А.В. Суворов

Последний раз редактировалось Ivan_32; 27.08.2011 в 21:28.
Ivan_32 вне форума Ответить с цитированием
Старый 27.08.2011, 19:57   #15
Zorgan
Пользователь
 
Аватар для Zorgan
 
Регистрация: 26.08.2011
Сообщений: 16
По умолчанию

Объектно-ориентированное программирование - это ООП надо полагать !!!

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

вы ошиблись в мелочах но есть скобки надо ставить после библиотек !

class StringData : public IData это класс чегото ?
поясните строки если не сложно или не в лом ?

конец ясен начало странное !!!
Zorgan вне форума Ответить с цитированием
Старый 27.08.2011, 21:30   #16
Ivan_32
somewhere else
Участник клуба
 
Аватар для Ivan_32
 
Регистрация: 17.07.2008
Сообщений: 1,409
По умолчанию

Чуть-чуть поправил, возможно так будет понятнее.
Вообще, я бы порекомендовал почитать Б.Страуструп Язык программирования C++, там у него такие вещи описаны.
"Тяжело в учении, легко в бою" - А.В. Суворов
Ivan_32 вне форума Ответить с цитированием
Старый 27.08.2011, 22:02   #17
Zorgan
Пользователь
 
Аватар для Zorgan
 
Регистрация: 26.08.2011
Сообщений: 16
По умолчанию

этот http://lib.ru/CPPHB/cpptut.txt

в общемто интересно это : Выбирающие операторы



Значение можно проверить с помощью операторов if или switch:

if ( выражение ) оператор

if ( выражение ) оператор else оператор

switch ( выражение ) оператор

В языке С++ среди основных типов нет отдельного булевского (тип
со значениями истина, ложь). Все операции отношений:

== != < > <= >=

дают в результате целое 1, если отношение выполняется, и 0 в противном
случае. Обычно определяют константы TRUE как 1 и FALSE как 0.
В операторе if, если выражение имеет ненулевое значение,
выполняется первый оператор, а иначе выполняется второй (если
он указан). Таким образом, в качестве условия допускается любое выражение
типа целое или указатель. Пусть a целое, тогда

if (a) // ...

эквивалентно

if (a != 0) ...

Логические операции

&& || !

обычно используются в условиях. В операциях && и || второй операнд
не вычисляется, если результат определяется значением первого
операнда. Например, в выражении

if (p && l<p->count) // ...

сначала проверяется значение p, и только если оно не равно нулю, то
проверяется отношение l<p->count.
Некоторые простые операторы if удобно заменять выражениями
условия. Например, вместо оператора

if (a <= b)
max = b;
else
max = a;

лучше использовать выражение

max = (a<=b) ? b : a;

Условие в выражении условия не обязательно окружать скобками, но
если их использовать, то выражение становится понятнее.
Простой переключатель (switch) можно записать с помощью
серии операторов if. Например,

switch (val) {
case 1:
f();
break;
case 2:
g();
break;
default:
h();
break;
}

можно эквивалентно задать так:

if (val == 1)
f();
else if (val == 2)
g();
else
h();

Смысл обеих конструкций совпадает, но все же первая предпочтительнее,
поскольку в ней нагляднее показана суть операции: проверка на
совпадение значения val со значением из множества констант. Поэтому в
нетривиальных случаях запись, использующая переключатель, понятнее.
Нужно позаботиться о каком-то завершении оператора, указанного
в варианте переключателя, если только вы не хотите, чтобы стали
выполняться операторы из следующего варианта. Например,
переключатель

switch (val) { // возможна ошибка
case 1:
cout << "case 1\n";
case 2:
cout << "case 2\n";
default:
cout << "default: case not found\n";
}

при val==1 напечатает к большому удивлению непосвященных:

case 1
case 2
default: case not found

Имеет смысл отметить в комментариях те редкие случаи, когда стандартный
переход на следующий вариант оставлен намеренно. Тогда этот переход
во всех остальных случаях можно смело считать ошибкой. Для
завершения оператора в варианте чаще всего используется break, но
иногда используются return и даже goto. Приведем пример:

switch (val) { // возможна ошибка
case 0:
cout << "case 0\n";
case1:
case 1:
cout << "case 1\n";
return;
case 2:
cout << "case 2\n";
goto case1;
default:
cout << "default: case not found\n";
return;
}

Здесь при значении val равном 2 мы получим:

case 2
case 1

Отметим, что метку варианта нельзя использовать в операторе goto:

goto case 2; // синтаксическая ошибка
но не очень понятно выбирающие кем прогой или человеком ?
Zorgan вне форума Ответить с цитированием
Старый 27.08.2011, 22:43   #18
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Мне кажется, что изучать С++ по Страуструпу не зная об операторах ветвления — не лучшая идея.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 28.08.2011, 02:34   #19
Blade
Software Engineer
Участник клуба
 
Аватар для Blade
 
Регистрация: 07.04.2007
Сообщений: 1,618
По умолчанию

Цитата:
Сообщение от Сtrl Посмотреть сообщение
Три. Или наследование предпочитаете приватное?
Согласен

Цитата:
Сообщение от Сtrl Посмотреть сообщение
По каким соображениям?
По соображениям хорошего стиля и хорошей читабельности.
Ключевое слово struct мигрировало в C++ из C, и использоваться оно должно так, как использовалось в C, т.е. для объявления пользовательского типа данных, который содержит только переменные-члены. Иногда допускается конструктор, но никак не виртуальные функции и наследование
Мужество есть лишь у тех, кто ощутил сердцем страх, кто смотрит в пропасть, но смотрит с гордостью в глазах. (с) Ария
Blade вне форума Ответить с цитированием
Старый 28.08.2011, 16:38   #20
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2Blade
Цитата:
но никак не виртуальные функции и наследование
наследование очень даже применяется, хотя и простейшее. функторы из stl, к примеру.

в общем случае, struct вместо class используется тогда, когда работаем либо с pod типом, либо с типом, который не может существовать сам по себе (те же функторы)
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 28.08.2011 в 16:40.
pproger вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Полиморфизм MasterSporta Общие вопросы C/C++ 3 10.04.2011 23:46
полиморфизм и констркуторы blacktener Общие вопросы C/C++ 4 06.03.2011 15:47
полиморфизм slayerblya Общие вопросы C/C++ 1 27.02.2011 01:43
Полиморфизм mister2010 Общие вопросы C/C++ 30 24.05.2010 01:07