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

Статическое связывание параметров методов - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
25.06.2011, 18:40     Статическое связывание параметров методов #1
Добрый день!
В коде (представлен ниже) сделал оболочки для константной и простой ссылок.
Известно, что в функции, которая ожидает константную ссылку, можно передать как конс-ю, так и простую ссылку. Поэтому наследую класс-оболочку константной ссылки классом-обол-й для простой ссылки. И, при проверке этого факта произошла ошибка, в ф-ции changeRef вызывает метод get() для базового класса - класса конст. ссылки, а не для класса простой ссылки, что, предполагая, должно было произойти. r_.get() должен связываться динамически, т.к. формальный параметр является ссылкой.
Почему формальный параметр не приводится по типу к дочернему?

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "StdAfx.h"
 
int v = 3;
int& x = v;
 
void changeRef(Cref<int>& r_)
{
    int& ptr = x;
    std::cout<<r_.get();
};
 
template <typename Object>
void getRef(Cref<Object>& r)
{
    std::cout<<r.get()<<"\n";
}
 
int main()
{
    Ref<int> r(x);
    const Cref<char> cr('a');
 
    changeRef(r);
    //getRef<int>(r);
    //getRef(cr);
 
    return 0;
}
 
Cref.h
#pragma once
#include "StdAfx.h"
 
template <typename Object>
class Cref
{
public:
    Cref() : ref(NULL) {}
    explicit Cref(const Object& r) : ref(&r) {}
    template <typename OtherObject>
    Cref(const Cref<OtherObject>& r) : ref(r.get()) {}
public:
    const Object& get() const
    {
        if(!isNull())
            return *ref;
        else
            throw NullPointerException();
    }
 
    bool isNull() const
    {
        return ref == NULL;
    }
private:
    const Object* ref;
};
 
Ref.h
 
#pragma once
#include "StdAfx.h"
 
template <typename Object>
class Ref : public Cref<Object>
{
public:
    Ref() : ref(NULL) {}
    explicit Ref(Object &r) : ref(&r) {}
    template <typename OtherObject>
    Ref(const Ref<OtherObject>& r) : ref(r.get()) {}
public:
    Object& get() 
    {
        return *ref;
    }
 
    Object& get() const
    {
        return *ref;
    }
private:
    Object* ref;
};
 
stdafx.h
 
#pragma once
 
#include <iostream>
#include <exception>
 
#include "NullPointerException.h"
#include "Cref.h"
#include "Ref.h"
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
26.06.2011, 18:19     Статическое связывание параметров методов #2
Цитата Сообщение от alexsvk Посмотреть сообщение
r_.get() должен связываться динамически, т.к. формальный параметр является ссылкой
Цитата Сообщение от alexsvk Посмотреть сообщение
Почему формальный параметр не приводится по типу к дочернему?
А почему он должен приводиться? В точке вызова компилятор видит объект типа Cref и знать не знает ни о каких производных классах. И почему он (компилятор) должен что-то к чему-то приводить?
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
26.06.2011, 18:31     Статическое связывание параметров методов #3
alexsvk, так ты сделай базовый класс полиморфным, добавь туда вирт. функцию...
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
26.06.2011, 19:50  [ТС]     Статическое связывание параметров методов #4
OstapBender, производный класс, используя методы с тем же названием, что и у базового, скрывает методы базового.

Evg,
Цитата Сообщение от alexsvk Посмотреть сообщение
changeRef(r);
вот точка вызова, где передаётся r типа Ref<int>, почему Вы упомянули объект типа Cref?
Приведение должно иметь место, т.к. использование передачи по ссылке (указателю) ведёт к динамическому связыванию, если речь идёт о базовом классе, как формальном параметре и дочернем, как фактическом. Так себе я это представляю.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
26.06.2011, 23:42     Статическое связывание параметров методов #5
Цитата Сообщение от alexsvk Посмотреть сообщение
вот точка вызова, где передаётся r типа Ref<int>, почему Вы упомянули объект типа Cref?
Ты писал "в ф-ции changeRef", вот я и смотрел в функцию changeRef, где у тебя вызывается метод get (9-я строка исходника). Тогда ставь вопрос более чётко, ибо тогда я не совсем понимаю, что не так
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
26.06.2011, 23:49  [ТС]     Статическое связывание параметров методов #6
Цитата Сообщение от Evg Посмотреть сообщение
Ты писал "в ф-ции changeRef", вот я и смотрел в функцию changeRef, где у тебя вызывается метод get (9-я строка исходника). Тогда ставь вопрос более чётко, ибо тогда я не совсем понимаю, что не так
Да, всё именно так. Но в фукнцию передаётся Ref, разве формальный параметр Cref - базовый класс для Ref не должен быть приведён к Ref?
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
27.06.2011, 00:01     Статическое связывание параметров методов #7
я кажется понял что ты хочешь.
передавай как хочешь, по ссылке или по значению, но так как твои классы не содержат виртуальных функций будет срабатывать раннее связывание. а формальный параметр знает только о базовом классе. собсно что и написали выше.
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
27.06.2011, 17:25  [ТС]     Статическое связывание параметров методов #8
Остался вопрос.
В классе Cref (класс-оболочка константной ссылки) есть метод get() - аксессор, возвращающий константную ссылку. Но как определить аксессор и мутатор get() для класса Ref, где будет возвращаться не константная ссылка?
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
27.06.2011, 21:31     Статическое связывание параметров методов #9
идея ясна, хочется одновременно разные возвращаемые значения и пользоваться динамо-полиморфизмом.
врятли так выйдет сделать с 1-м именем функции, ибо перегрузка только по возвр. значению запрещена вообще, к тому же если изменить атрибуты функции это будет уже не измененная функция а её перегруженный вариант. то есть не катит.

в голову приходят только замуты с динамик кастом.

в getref
C++
1
2
3
4
5
6
7
8
9
10
11
template <typename Object>
void getRef(Cref<Object>& r) {
 
try {
Ref temp_o=dynamic_cast<Ref<Object>&>(r);
std::cout << temp_o.getNotConst(); // этот метод определить в производном
} catch(std::bad_cast) {
std::cout << r.get();
}
 
}
поправляйте если где-то накосячил.
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
27.06.2011, 22:07  [ТС]     Статическое связывание параметров методов #10
OstapBender, твой вариант, что называется, "в лоб"
Не помню, где первично, но вот сейчас в памяти своей прочёл идейку. Проиллюстрирую.
C++
1
2
3
4
5
6
7
8
9
10
11
12
class get
{
public:
get(Cref* cp_ = NULL, Ref* p_ = NULL) : cp(cp_), p(p_) {}
operator Ref() ()
{if (p) return p->get();}
operator Cref() ()
{if (cp) return cp->get();}
private:
const Cref* cp;
const Ref* p;
};
Имеем функциональный объект, который можно сделать friend к Ref, Cref.
А можно проще, сделать get() статическим и вызывать Cref::get() и дальше по тексту.
Нужно испробовать, конечно.

Добавлено через 17 минут
Для наглядности, использование в функции.
C++
1
2
3
4
5
template <typename Object>
void getRef(Cref<Object>& r)
{
        std::cout<<((typeid(r))get(&r));<<"\n";
}
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
27.06.2011, 22:21     Статическое связывание параметров методов #11
alexsvk, дык когда ты конструируешь объект типа get переменной &r допустим производного класса, она все равно подходит по критерию Cref* cp_

кстати оператор приведения типа имеет синтаксис operator Ref()

да к тому же с добавлением нового потомка придется всё равно писать новый оператор приведения, так что проблему это не решает.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.06.2011, 23:26     Статическое связывание параметров методов
Еще ссылки по теме:

Статическое приведение типов C++
Статическое подключение системных DLL-файлов C++
C++ Статическое объявление матрицы

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

Или воспользуйтесь поиском по форуму:
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
27.06.2011, 23:26  [ТС]     Статическое связывание параметров методов #12
OstapBender, не учёл. Тогда можно сделать так
C++
1
2
3
4
5
template<typename T>
class get
{...
private:
T* p;}
где T будет задаваться как typeid(Object).
Т.е. как пример (typeid(object))(get<typeid<object>(&r));
Yandex
Объявления
27.06.2011, 23:26     Статическое связывание параметров методов
Ответ Создать тему
Опции темы

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