Форум программистов, компьютерный форум CyberForum.ru

Полиморфизм, дружественные функции - C++

Восстановить пароль Регистрация
 
Hugo_Boss
1 / 1 / 0
Регистрация: 29.01.2013
Сообщений: 46
10.07.2013, 13:37     Полиморфизм, дружественные функции #1
Всем привет!

Имеется такая конструкция:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Base {
public:
  Base();
  Base(int n) {};
  virtual ~Base() {};
 
  const Base& operator+=(int n);
  friend Base operator+(Base &base, int n) {
    Base new_base(n);
    //... 
    new_base += base;
    return new_base;
  }
};
 
class Derive1 : public Base {
public:
  Derive1() {};
  Derive1(Derive1 &der) {};
  Derive1(int n) {};
  ~Derive1();
 
  const Derive1& operator+=(int n) {...};
private:
  int n;
};
 
class Derive2 : public Base {
  Derive2();
  Derive2(Derive2 &der) {};
  Derive2(int n) {};
  ~Derive2();
 
  const Derive2& operator+=(int n) {...};
private:
  int n;
};
Класс Base я делаю как интерфейс, и все общие методы я стремлюсь вынести именно в него. Вот я вынес в него оператор+.
Я хочу сделать что-то типа:

C++
1
2
3
4
Base base = ...;
Derive1 der1 = ...;
Derive2 der2 = ...;
base = der1 + der2;
Возможно так сделать?
В том виде, что я написал здесь, у меня выдается ошибка линковщика (неразрешенный внешний символ).

Спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.07.2013, 13:37     Полиморфизм, дружественные функции
Посмотрите здесь:

C++ Дружественные функции
C++ Дружественные функции
Дружественные функции C++
C++ дружественные функции
C++ Дружественные функции
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Мимино
 Аватар для Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
10.07.2013, 14:21     Полиморфизм, дружественные функции #2
То, что заметил.
1. Для
C++
1
2
3
4
Base base = ...;
Derive1 der1 = ...;
Derive2 der2 = ...;
base = der1 + der2;
не перегружен оператор присваивания.
2. При такой перегрузке оператора сложения
C++
1
friend Base operator+(Base &base, int n)
такое невозможно
C++
1
der1 + der2;
3.
C++
1
new_base += base;
не будет работать при
C++
1
const Base& operator+=(int n);
Hugo_Boss
1 / 1 / 0
Регистрация: 29.01.2013
Сообщений: 46
10.07.2013, 14:26  [ТС]     Полиморфизм, дружественные функции #3
Цитата Сообщение от Мимино Посмотреть сообщение
2. При такой перегрузке оператора сложения

C++
1
friend Base operator+(Base &base, int n)
такое невозможно
C++
1
der1 + der2;
А можно, пожалуйста, объяснить, почему такое невозможно? И какая нужна перегрузка, чтобы заработало?
Спасибо.
Мимино
 Аватар для Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
10.07.2013, 14:28     Полиморфизм, дружественные функции #4
ну и самое главное. Дружественные функции не наследуются
Hugo_Boss
1 / 1 / 0
Регистрация: 29.01.2013
Сообщений: 46
10.07.2013, 14:33  [ТС]     Полиморфизм, дружественные функции #5
Цитата Сообщение от Мимино Посмотреть сообщение
Дружественные функции не наследуются
Да, я понимаю.

И что, нельзя сделать (пусть костыльно - хоть принцип увидеть) так, как я хочу?
Мимино
 Аватар для Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
10.07.2013, 14:48     Полиморфизм, дружественные функции #6
Цитата Сообщение от Hugo_Boss Посмотреть сообщение
А можно, пожалуйста, объяснить, почему такое невозможно? И какая нужна перегрузка, чтобы заработало?
Спасибо.
C++
1
(Base &base, int n)
Эта перегрузка может складывать объект класса Base с объектом int. Когда вы вызываете der1 + der2, это равносильно:
C++
1
der1.operator+(der2)
Чтобы заработало:
1. Убрать дружественность и сделать функцию обычной функцией - элементом (конечно, если у Вас не будет записей типа int + YourClassObj).
2. Решить что и с чем Вы собираетесь складывать/
3. Описать алгоритм сложения

Добавлено через 9 минут
Вот тут могу ошибаться, поэтому поправьте меня люди добрые
1. Дружественность не наследуется. Для каждого производного класса нужно будет переопределять дружественную функцию.
2. При чем тут полиморфизм? "Загнав" все методы в базовый класс Вы не сможете вызвать метод производного класса через указатель базового класса, а ровно наоборот.

Вопрос. Чего конкретно вы хотите добиться? Полиморфизм или наследование методов базового класса?
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
10.07.2013, 16:32     Полиморфизм, дружественные функции #7
Цитата Сообщение от Мимино Посмотреть сообщение
Дружественность не наследуется. Для каждого производного класса нужно будет переопределять дружественную функцию.
Можно достучаться через базовый класс:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
 
using namespace std;
 
class B;
void f( const B& b );
 
class B
{
    friend void f( const B& b );  
    int p = 42;    
    virtual int getP() const { return p; }
};
 
class D : public B
{
    virtual int getP() const { return p; }
    int p = 100500;
};
 
void f( const B& b )
{
    cout << b.getP() << endl;
    //cout << dynamic_cast<const D&>(b).getP() << endl; // так уже нельзя
}
 
int main() {
    B b;
    f( b );
    
    D d;
    f( d );
    
    return 0;
}
https://ideone.com/fHOIsh
Мимино
 Аватар для Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
10.07.2013, 16:58     Полиморфизм, дружественные функции #8
Цитата Сообщение от Tulosba Посмотреть сообщение
Можно достучаться через базовый класс:
C++
1
int p = 42;
как это пропускает? На сколько я знаю, так нельзя
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
10.07.2013, 17:00     Полиморфизм, дружественные функции #9
Цитата Сообщение от Мимино Посмотреть сообщение
как это пропускает? На сколько я знаю, так нельзя
C++11
non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
Мимино
 Аватар для Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
10.07.2013, 17:11     Полиморфизм, дружественные функции #10
Цитата Сообщение от Tulosba Посмотреть сообщение
C++11
понял

Добавлено через 6 минут
Одно не могу понять. Гугл говорит, что дружественность не наследуется, то есть функция f не может иметь доступ к закрытым элементам класса D, но пример доказывает обратное. В чем подвох? Где можно почитать?

Добавлено через 3 минуты
Все, я расчехлился.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
10.07.2013, 17:20     Полиморфизм, дружественные функции #11
Цитата Сообщение от Мимино Посмотреть сообщение
но пример доказывает обратное
в примере доступ идет через виртуальную функцию базового класса, а вот явный вызов функции производного класса уже не получается сделать (закомментированная часть).
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.07.2013, 17:23     Полиморфизм, дружественные функции
Еще ссылки по теме:

Дружественные функции С++ C++
C++ Дружественные функции. Наследование. Перегрузка функции
Дружественные функции C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Мимино
 Аватар для Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
10.07.2013, 17:23     Полиморфизм, дружественные функции #12
Цитата Сообщение от Tulosba Посмотреть сообщение
в примере доступ идет через виртуальную функцию базового класса, а вот явный вызов функции производного класса уже не получается сделать (закомментированная часть).
Да, я понял, спасибо. Как раз сейчас заканчиваю главу "Полиморфизм и виртуальные функции". Этот пример как раз то, чего мне не хватало для понимания общей картины
Yandex
Объявления
10.07.2013, 17:23     Полиморфизм, дружественные функции
Ответ Создать тему
Опции темы

Текущее время: 14:38. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru