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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.83
Ilot
Модератор
Эксперт С++
1807 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 5
Завершенные тесты: 1
#1

Как работает компилятор при создании объекта - C++

25.10.2013, 13:06. Просмотров 1537. Ответов 36
Метки нет (Все метки)

Таки думал разобрался как работает конструктор копирования, а выходит, что нет.
Вопрост состоит в следующем. Имеем код представляющий собой класс для хранения указателей на строки которые хранятся в другом классе(суть в том что бы не хранить в памяти несколько копия строк если они идентичны):
Кликните здесь для просмотра всего текста
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
#include<iostream>
using namespace std;
////////////////////////////////////////////////////////
class strCount
{
private:
    char* str;
    int count;
    friend class String;
    strCount(char * s)
    {
        str = new char [strlen(s) + 1];
        strcpy(str, s);
        count++;
    }
    ~strCount()
    {
        delete [] str;
    }
};
///////////////////////////////////////////////////
class String
{
private:
    strCount* psc;
public:
    String()
    {
        psc = new strCount("NULL");
    }
 
    String(char* s)
    {
        psc = new strCount(s);
    }
 
    String(String& S)
    {
        psc = S.psc;
        (psc->count)++;
    }
 
    ~String()
    {
        if(psc->count == 1)
            delete psc;
        else
            (psc->count)--;
    }
    String& operator = (String& S)
    {
        if(psc->count == 1)
            delete psc;
        else
            (psc->count)--;
        psc = S.psc;
        (psc->count)++;
        return *this;
    }
    void display()
    {
        cout << psc->str << endl;
    }
};
////////////////////////////////////////////////////
int main()
{
    system("chcp 1251>0");
    String s3 = "Немного лет тому назад, там где сливаяся шумят";
 
    cout << "s3= "; s3.display();
    return 0;
}

Когда я в первый раз читал Лафоре этот код отлично компилился(в то время я работал в VS 6.0).
В данный момент я программирую в среде Code::Blocks и в ней данный код не компилится. Ругается на неоднозначное определение конструктора. Вот отсюда и вопрос:
А что собственно происходит при создании объекта?
Когда запускается конструктор копирования, а когда конструктор с одним аргументом?
Все это время я полагал, что сперва запускается конструктор копирования, а вот он в свою очередь вызывает конструктор с одним аргументом.
Таки все же я не прав или как? Просвятите пожайлуста.

Добавлено через 5 минут
Странно. Конструктор копирования в VS не вызывается...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.10.2013, 13:06     Как работает компилятор при создании объекта
Посмотрите здесь:

Компилятор выдает ошибку при создании списка - C++
Доброго времени суток всем, не могу понять где ошибка создаю список list самым простым способом #include &lt;list&gt; #include...

Вылет программы при создании объекта - C++
Начал изучать классы с создания класса для работы с массивами, класс должен работать как с одномерными так и двумерными динамическими...

Undefined reference при создании объекта - C++
Есть класс Engine и функция для его инициализации - CreateEngine при попытке создать объект с помощью Engine *engine =...

Ошибка при создании объекта класса - C++
Здравствуйте. В коде ниже при попытке вывести код на экран возникает следующая ошибка: prog.cpp: In function 'int main()': ...

При создании объекта структуры не вызываются конструкторы - C++
Есть класс Время. У него есть два конструктора. Создал структуру struct List { Time a; List *next; }; При создании объекта...

Ключевое слово class при создании объекта - C++
class A { int r; }; int main () { class A w;//Для чего здесь ключевое слово class? ... }

Ошибки при создании объекта в другом файле - C++
a.h struct Coords { int x; int y; Coords() {}; Coords(int mX, int mY) { x = mX; y = mY; } };

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Raali
623 / 327 / 34
Регистрация: 06.07.2013
Сообщений: 1,056
Завершенные тесты: 1
25.10.2013, 13:13     Как работает компилятор при создании объекта #2
Цитата Сообщение от Ilot Посмотреть сообщение
Странно. Конструктор копирования в VS не вызывается...
Цитата Сообщение от Ilot Посмотреть сообщение
String s3 = "Немного лет тому назад, там где сливаяся шумят";
это обычный конструктор
C++
1
String(char* s)
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
25.10.2013, 13:17     Как работает компилятор при создании объекта #3
copy constructor применяется, например, так:

C++
1
2
MyClass ob;
MyClass copy = ob;
у тебя перегружен оператор =, я не могу точно сказать, что произойдет с твоим классом в этом случае. поисследуй, разберись, расскажешь.
Ilot
Модератор
Эксперт С++
1807 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 5
Завершенные тесты: 1
25.10.2013, 13:20  [ТС]     Как работает компилятор при создании объекта #4
Цитата Сообщение от novi4ok Посмотреть сообщение
у тебя перегружен оператор =, я не могу точно сказать, что произойдет с твоим классом в этом случае. поисследуй, разберись, расскажешь.
Методом научного тыка выяснилось, что компилятор VS таки адекватно подходит к выбору конструктора:
Тута вызывется конструктор с одним аргументом:
C++
1
    String s3 = "Немного лет тому назад, там где сливаяся шумят";
А здеся конструктор копирования:
C++
1
    String s1(s3);
Так чего от меня хочет Code::Blocks? Как работает его компилятор? Т.е. я хочу спросить как определено поведение компилятора с точки зрения стандарта?

Добавлено через 53 секунды
Цитата Сообщение от novi4ok Посмотреть сообщение
у тебя перегружен оператор =, я не могу точно сказать, что произойдет с твоим классом в этом случае. поисследуй, разберись, расскажешь.
Не. Перегрузка оператора тут не причем. Это разные вещи.
Raali
623 / 327 / 34
Регистрация: 06.07.2013
Сообщений: 1,056
Завершенные тесты: 1
25.10.2013, 13:24     Как работает компилятор при создании объекта #5
Цитата Сообщение от Ilot Посмотреть сообщение
Как работает его компилятор?
смотря какой в нем компилятор
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,076
Записей в блоге: 10
Завершенные тесты: 1
25.10.2013, 13:28     Как работает компилятор при создании объекта #6
Цитата Сообщение от Raali Посмотреть сообщение
смотря какой в нем компилятор
Обычно GCC.

Ilot, ты много всего к кучу смешал. Давай рассмотрим вариант попроще:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cstring>
 
class A {
    char m_data[256];
 
public:
 
    A( char * s ) {
        strcpy( m_data, s );
    }
 
    A( A & a ) {
        strcpy( m_data, a.m_data );
    }
};
 
int main() {
    A a = "test";
}
Здесь Code::Blocks скорее всего выведет ошибку. Но если в конструкторе перед типом аргумента поставить const то он его съест.
Ilot
Модератор
Эксперт С++
1807 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 5
Завершенные тесты: 1
25.10.2013, 13:28  [ТС]     Как работает компилятор при создании объекта #7
Цитата Сообщение от Raali Посмотреть сообщение
смотря какой в нем компилятор
Ну так таки в Code::Blocks я пробывал несколько компиляторов: GCC, MV C++ 2005, MV C++ 2010. Все кричат об одно и том же.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
25.10.2013, 13:47     Как работает компилятор при создании объекта #8
Raali, Отнюдь, строка которая вы процитировали
C++
1
String s3 = "Немного лет тому назад, там где сливаяся шумят";
Является ничем иным как
C++
1
String s3(String("Немного лет тому назад, там где сливаяся шумят"));
Конструктор копии вызывается, но на самом деле вызов не обязателен (copy-elision).

Добавлено через 30 секунд
novi4ok, Это не является вызовом конструктор копирования, это именно вызов оператора присваивания.

Добавлено через 3 минуты
Ilot, Код не будет компилироваться ни на одном нормальном компиляторе. Компилятор, даже если не вызывает конструктор копирования ОБЯЗАН проверить, что подходящий конструктор копирования существует. Здесь же, из-за того, что конструктор копирования принимает ссылку, нужного конструктора копирования нет, т.к. нельзя привести временный объект к ссылке (в MSVC это компилируется, потому что он допускает как расширение биндинг временного объекта к ссылке).
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
25.10.2013, 13:49     Как работает компилятор при создании объекта #9
Цитата Сообщение от ForEveR Посмотреть сообщение
Это не является вызовом конструктор копирования, это именно вызов оператора присваивания.
ошибаешься, таки копирования. оператор присваивания вызывается здесь:

C++
1
2
3
MyClass ob;
MyClass ob2;
ob = ob2;
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
25.10.2013, 13:51     Как работает компилятор при создании объекта #10
novi4ok, Да, извиняюсь, согласен, затормозил. Не заметил, что идет инициализация, а не присваивания уже созданному объекту.
Ilot
Модератор
Эксперт С++
1807 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 5
Завершенные тесты: 1
25.10.2013, 13:54  [ТС]     Как работает компилятор при создании объекта #11
Мда castaway сделал как вы сказали заработало как я и говорил в первом посте. Т.е. сперва вызывается конструктор копирования, затем конструктор с одним аргументом. Насколько я понимаю конструктор копирования вызывается так как аргумент это константный указатель и конструктор копирования более подходит к данной ситуации. Однако почему в исходном варианте не вызывается конструктор с одним аргументом - ведь он в точности соответствует аргументам?
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
25.10.2013, 13:57     Как работает компилятор при создании объекта #12
Ilot,
Цитата Сообщение от Ilot Посмотреть сообщение
Т.е. сперва вызывается конструктор копирования, затем конструктор с одним аргументом.
Вообщем-то наоборот. Сначала с одним аргументом, а потом конструктор копирования с передачей в него вновь созданного объекта.
Ilot
Модератор
Эксперт С++
1807 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 5
Завершенные тесты: 1
25.10.2013, 14:03  [ТС]     Как работает компилятор при создании объекта #13
Цитата Сообщение от ForEveR Посмотреть сообщение
Ilot,
Вообщем-то наоборот. Сначала с одним аргументом, а потом конструктор копирования с передачей в него вновь созданного объекта.
Снова ошибаетесь уважаемый Сперва именно копирования, который вызывает с одним. Проверенно:
Миниатюры
Как работает компилятор при создании объекта  
Ilot
Модератор
Эксперт С++
1807 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 5
Завершенные тесты: 1
25.10.2013, 14:06  [ТС]     Как работает компилятор при создании объекта #14
Цитата Сообщение от ForEveR Посмотреть сообщение
Здесь же, из-за того, что конструктор копирования принимает ссылку, нужного конструктора копирования нет, т.к. нельзя привести временный объект к ссылке (в MSVC это компилируется, потому что он допускает как расширение биндинг временног
Я в замешательстве... А разве в конструкторе копирования можно передавать аргумент по значению?
Не приведет ли это к ошибке?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.10.2013, 14:07     Как работает компилятор при создании объекта
Еще ссылки по теме:

Ошибка LNK2019 При динамическом создании объекта - C++
Это хидер который я создал #include&lt;math.h&gt; #define PI 3.14 class Figure { public: Figure(); virtual ~Figure();

ООП в C++: Вызов родительского конструктора с параметром при создании объекта дочернего класса - C++
Здравствуйте! Столкнулся с такой проблемой: если есть родительский класс с конструктором, то при создании дочернего объекта от этого...

Как работает компилятор С++ - C++
Подскажите, как происходит компиляция исходного кода, написанного на С++? К примеру мы имеем файл test.cpp, в котором написан код...

Не работает класс при передаче в функцию объекта - C++
Всем привет, я не пойму подскажите куда правильно подставить #include &quot;doodler.h&quot; чтобы не было ошибок. Есть класс, который содержит...

Как компилятор узнаёт о размере массива при выполнении операции delete? - C++
Такой глупый вопрос появился при изучении операций new и delete. Я создаю указатель на массив int с помощью операции new. int size; ...


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

Или воспользуйтесь поиском по форуму:
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,076
Записей в блоге: 10
Завершенные тесты: 1
25.10.2013, 14:07     Как работает компилятор при создании объекта #15
Цитата Сообщение от ForEveR Посмотреть сообщение
Вообщем-то наоборот.
Да, мне тоже сначала так показалось.. Но по факту вызывается только один конструктор A( char * s ), что по-сути вроде как и является правильным. Зачем тут конструктор копирования?
Единственный момент, который еще следует поправить, так это изменить конструктор на A( const char * s )
Поправьте если в чем-то ошибся.

Ilot, я предлагаю рассматривать вариант попроще, например мой, и уже от него отталкиваться.
Yandex
Объявления
25.10.2013, 14:07     Как работает компилятор при создании объекта
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru