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

Особенности использования указателей и ссылок в C++ при возврате из функции - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Динамическое создание форм (Не MFC) http://www.cyberforum.ru/cpp-beginners/thread933230.html
Допустим есть созданная форма в ресурснике, а в ней есть поле для ввода(Edit Control) и даже кнопка(Button)! :) Подскажите пожалуйста, как заставить Button создать еще одно поле для ввода? :) ЗЫ:Для тех, кто любит делать умный вид и спрашивать "А на каком языке?", скажу сразу(хоть и так вопрос лежит в разделе С++) на C++! :) ЗЫЫ:Не MFC. ЗЗЫЫ: Заранее благодарен за ответы. :)
C++ allocate, как работает? template<class T> class Vec { public: typedef T* iterator; typedef const T* const_iterator; typedef size_t size_type; typedef T value_type; typedef T& reference; typedef const T& const_reference; http://www.cyberforum.ru/cpp-beginners/thread933209.html
C++ Функция ввода вместо cin
Здорова! Нужно написать функцию ввода вместо cin, которая бы читала строки. Я не знаю чем можно заменить cin. Нужно постараться сделать так что бы по быстродействию функция читала строки быстрее чем cin (строки определенной длинны 15-20 символов). Как это сделать? И вообще чем можно заменить cin?
C++ Программирование и Английский
Подскажите форумы на английском языке, на подобии этого. Что были очень много посещаемы, и был раздел специально для С++. Это для практики по английскому.
C++ Не могу понять синтаксис C++ http://www.cyberforum.ru/cpp-beginners/thread933139.html
как понять данные строки кода, вроде бы наследование, а вроде бы и нет, так как в начале стоит конструктор MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { //ui->setupUi(this); }
C++ Создание WinAPI контролов с ручной настройкой параметров Контролы в WinAPI это те же окна, поэтому создаются через CreateWindowEx. А как можно создать компонент (допустим, Memo), поместить его на диалоговое окно, но при этом чтобы можно было изменять его положение или размер? Не совсем пойму что нужно делать после "Креате".:scratch: подробнее

Показать сообщение отдельно
zer0mail
2332 / 1958 / 192
Регистрация: 03.07.2012
Сообщений: 7,021
Записей в блоге: 1

Особенности использования указателей и ссылок в C++ при возврате из функции - C++

04.08.2013, 11:59. Просмотров 889. Ответов 16
Метки (Все метки)

Пусть у нас есть некий класс CBase и есть функция, которая создает и возвращает объект класса CBase. Создать она его может стеке или в куче, а вернуть может сам объект, ссылку на него или указатель… Чем же различаются эти варианты? Для ответа напишем простой тест, использующий разные варианты и сравним.
Кликните здесь для просмотра всего текста

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
class CBase
{
public:
    int i;
    // конструктор по-умолчанию
    CBase()     
    {  
        i=0;
        name = NULL;  
        cout<<"Base() "<<endl;
    }
 
    CBase(const char *str1)     
    {  
        i=1;
        name = new char[strlen(str1)+1];  
        strcpy(name, str1); 
        cout<<"Base "<<i<<" "<<name<<endl;
    }
    // конструктор копирования, создает новую строку с добавлением @ в начале
    CBase(CBase &b)     
    {  
        i=2;
        name = new char[strlen(b.name)+2];  
        name[0]='@';
        strcpy(name+1, b.name); 
        cout<<"CopyBase "<<i<<" "<<name<<endl;
    }
    CBase & operator = (const CBase& b)
    {   i=3;
        cout<<"Base = "<<i<<" "<<name<<endl;
        return *this;
    }
    virtual ~CBase()                          
    { 
        cout<<"~Base "<<i<<" "<<name<<endl;
        delete [] name;
    }
    void SetString(const char *str1) {
        delete [] name;
        name = new char[strlen(str1)+1];  
        strcpy(name, str1); 
    }
protected:
    char *name;
};
 
class CDerived : public CBase
{
public:
    CDerived(const char *str1, const char *str2) 
        : CBase(str1)   
    { 
        name2 = new char[strlen(str2)+1];  
        strcpy(name2, str2);
        cout<<"Derived "<<name2<<endl;
    }
      ~CDerived()                                             
    {  
//      CBase::~CBase(); // а вот этого - не надо
        delete [] name2;
        cout<<"~Derived "<<name2<<endl;
    }
protected:
    char *name2;
};
 
// функции именуются так: get<символ возврата><символ создания>
//символ создания - как новый объект создается в процедуре:
// p - через new (p-указатель на созданный объект)
// o - через локальную переменную (o- локальная переменная)
//символ возврата - как новый объект возвращается в вызывающую процедуру:
// p - возвращается указатель на созданный объект
// о - возвращается сам созданный объект
// ro- возвращается ссылка на созданный объект
 
CBase *getpp(char* str) {
    CBase *p=new CBase(str);
    return p;
}
CBase getop(char* str) {
    CBase *p=new CBase(str);
    return *p;
}
CBase getoo(char* str) {
    CBase o(str);
    return o;
}
 
CBase& getrp(char* str) {
    CBase *p=new CBase(str);
    return *p;
}
 
CBase& getro(char* str) {
    CBase o(str);
    return o;
}
 
CBase* getpo(char* str) {
    CBase o(str);
    return &o;
}
 
void fun()
{
    CBase *pp=getpp("PP str1");     //+ новый объект создан в куче, на него вернули указатель. Потом надо не забыть удалить объект delete pp;
    CBase *po=getpo("PO str2");     //- локальный объект тут же удаляется, указатель на удаленный объек
    CBase op=getop("OP str3");      //- новый объект создан в куче, потом он копируется. НО старый объет остался в куче, т.е произошла утечка памяти
    CBase oo=getoo("OO str4");      //+ новый объект копируется, локальный удаляется. ВСЕ ОК. 
    CBase oro=getro("ORO str5");    //- локальный объект сначала удаляется, потом копируется! тяжелый случай
    CBase orp=getrp("ORP str6");    //- новый объект создан в куче, потом он копируется. НО старый объет остался в куче, т.е произошлаа утечка памяти
    CBase &rro=getro("RRO str7");   //- локальный объект тут же удаляется, ссылка на удаленный объект
    CBase &rrp=getrp("RRP str8");   //+ новый объект создан в куче, на него вернули ссылку. Но его надо не забыть удалить delete &rrp
    CBase o=oo; // копируется
    o=orp; // копируется
    
    // удаление объектов
    delete pp;
    delete &rrp; // ручное
    cout<<"Конец функции"<<endl;
}

А вот результат выполнения fun(), на основании которого сделаны комментарии:
Кликните здесь для просмотра всего текста

Base 1 PP str1
Base 1 PO str2
~Base 1 PO str2
Base 1 OP str3
CopyBase 2 @OP str3
Base 1 OO str4
CopyBase 2 @OO str4
~Base 1 OO str4
Base 1 ORO str5
~Base 1 ORO str5
CopyBase 2 @H€A
Base 1 ORP str6
CopyBase 2 @ORP str6
Base 1 RRO str7
~Base 1 RRO str7
Base 1 RRP str8
CopyBase 2 @@OO str4
Base = 3 @@OO str4
~Base 1 PP str1
~Base 1 RRP str8
Конец функции
~Base 3 @@OO str4
~Base 2 @ORP str6
~Base 2 @H€A
~Base 2 @OO str4
~Base 2 @OP str3

Выводы:
Из 8 рассмотренных вариантов осталось 3.
1-й и 8-й варианты создают объект в куче, нет копирования (не тратится время). НО их надо удалять.
4-й тоже неплох (если знаешь, как происходит копирование и объект небольшой).

В общем 1-й и 4-й варианты работают так, словно объект создан через конструктор.
А 8-й удобен в плане использования: обращение к полям через точку '.' (как в 4), но необходимость удаления объекта неочевидна.
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru