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

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

Войти
Регистрация
Восстановить пароль
 
DannyConnor
2 / 2 / 0
Регистрация: 11.10.2015
Сообщений: 38
Завершенные тесты: 1
#1

константная ссылка в качестве аргумента конструктору копирования - C++

12.08.2016, 12:10. Просмотров 161. Ответов 2
Метки нет (Все метки)

доброго времени суток! реализую класс String для работы со строками, программа не компилируется, если я передаю в качестве аргумента константную ссылку класса String в конструктор копирования и работает, если убираю const (и в заголовке, и в определении). До этого было с точностью наоборот (без const не работало). см вложение

Visual Studio Community 2015
в g++ нормально компилирует и так, и так, не считая предупреждения

Source.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <conio.h>
#include "String.h"
 
using namespace::std;
using Programm::String;
 
int main(int argc, char** arhv) {
    setlocale(LC_ALL, "Russian");
 
    String st1("Alexandra");
    String st2(st1);
 
    cout << st1 << endl;
    cout << st2 << endl;
 
    _getch();
    return 0;
}
String.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma once
#include <iostream>
#include <cstring>
 
namespace Programm
{
    class String
    {
    private:
        char* str;
        int length;
    public:
        String();
        String(char*);
        String(const String&);
        friend std::ostream& operator<<(std::ostream&, String&);
        ~String();
    };
 
}
String.cpp
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
#include "String.h"
 
namespace Programm
{
    String::String() {
        str = NULL;
        length = 0;
    }
    String::String(char* st) {
        length = strlen(st);
        str = new char[length+1];
        for (int i(0); i < length; i++)
            str[i] = st[i];
        str[length] = '\0';
    }
 
    String::String(const String& st) {
        length = strlen(st.str);
        str = new char[length + 1];
        for (int i(0); i < length; i++)
            str[i] = st.str[i];
        str[length] = '\0';
    }
 
    std::ostream& operator<<(std::ostream& os, String& st) {
        os << st.str;
        return os;
    }
 
    String::~String() {
        delete[] str;
    }
}
Миниатюры
константная ссылка в качестве аргумента конструктору копирования  
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.08.2016, 12:10     константная ссылка в качестве аргумента конструктору копирования
Посмотрите здесь:

Функция в качестве аргумента C++
C++ Передача функции в качестве аргумента массив
Передача двухмерного массива в качестве аргумента C++
Использование массивов в качестве аргумента функции C++
Передача символьного массива в качестве аргумента C++
Как в качестве аргумента функции передать массив? C++
C++ Как передать функцию в качестве аргумента?
C++ Передача матрицы в метод в качестве аргумента
Почему говорят "константная ссылка"? C++
C++ Шаблон в качестве аргумента метода(функции)
C++ Передача массива в качестве аргумента функции
C++ Использование массива в качестве аргумента функции

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
John Prick
758 / 691 / 124
Регистрация: 27.07.2012
Сообщений: 1,980
Завершенные тесты: 3
12.08.2016, 12:19     константная ссылка в качестве аргумента конструктору копирования #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Так это линкер ругается, что не может найти реализацию конструктора с неконстантным параметром. Очисти выходной каталог и пересобери проект.

ПС. Зачем делать length = strlen(st.str), если длина уже есть в передаваемой строке: length = st.length.
DENIS94
22 / 22 / 0
Регистрация: 12.04.2013
Сообщений: 122
12.08.2016, 15:55     константная ссылка в качестве аргумента конструктору копирования #3
Можно сделать например так:

main.cpp
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
#include <iostream>
 
#include "mstring.h"
 
mtype::string func()
{
    return mtype::string("rvalue");
}
 
int main(int , char *[])
{
    using namespace mtype;
 
    string s = "qweqweqwe";
    string z = "asdasdasd";
    s = z;
    z = "hello world!";
    z = string("12345");
    string w;
    w = std::move(func());
 
    std::cout << s << std::endl;
    std::cout << z << std::endl;
    std::cout << w << std::endl;
 
    std::cout << w[2] << std::endl;
 
    return 0;
}
mstring.h
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
#ifndef MSTRING_H
#define MSTRING_H
 
#include <memory>
#include <utility>
#include <cstring>
#include <iostream>
 
namespace mtype
{
 
class string
{
private:
    typedef unsigned char tdata;
    struct data
    {
        tdata     * m_str;
        std::size_t m_size;
        data(tdata * str = nullptr, std::size_t size = 0) :
            m_str(str),
            m_size(size)
        {}
    };
 
public:
    inline ~string();
 
    inline string();
    inline string(const char * str);
    inline string(const string & str);
    inline string & operator=(const char * str);
    inline string & operator=(const string & str);
 
    inline string(string && str);
    inline string & operator=(string && str);
 
    inline tdata & operator[](std::size_t i);
 
    friend std::ostream & operator<<(std::ostream & stream, const string & s);
 
private:
    void copyData(const tdata * str, std::size_t sz);
 
private:
    data * m_d;
};
 
inline string::~string()
{
    if (m_d)
    {
        if (m_d->m_str) delete[] m_d->m_str;
        delete m_d;
    }
}
 
inline string::string() :
    m_d(new data{})
{}
 
inline string::string(const char * str) :
    m_d(new data(nullptr, std::strlen(str)))
{
    m_d->m_str = new tdata[m_d->m_size + 1];
    m_d->m_str[m_d->m_size] = 0;
    std::memcpy(m_d->m_str, str, m_d->m_size);
}
 
inline string::string(const string & str) :
    m_d(new data(nullptr, str.m_d->m_size))
{
    m_d->m_str = new tdata[m_d->m_size + 1];
    m_d->m_str[m_d->m_size] = 0;
    std::memcpy(m_d->m_str, str.m_d->m_str, m_d->m_size);
}
 
inline string & string::operator=(const char * str)
{
    copyData(reinterpret_cast<const tdata*>(str), std::strlen(str));
    return (*this);
}
 
inline string & string::operator=(const string & str)
{
    copyData(str.m_d->m_str, str.m_d->m_size);
    return (*this);
}
 
inline string::string(string && str) :
    m_d(str.m_d)
{
    str.m_d = nullptr;
}
 
inline string & string::operator=(string && str)
{
    std::swap(m_d, str.m_d);
    return (*this);
}
 
inline string::tdata & string::operator[](size_t i)
{
    return m_d->m_str[i];
}
 
inline std::ostream & operator<<(std::ostream & stream, const mtype::string & s)
{
    stream << s.m_d->m_str;
    return stream;
}
 
}
 
#endif // MSTRING_H
mstring.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "mstring.h"
 
namespace mtype
{
 
void string::copyData(const tdata * str, size_t sz)
{
    if (!m_d->m_str) m_d->m_str = new tdata[sz + 1];
    else
    {
        if (m_d->m_size != sz)
        {
            delete m_d->m_str;
            m_d->m_str = new tdata[sz + 1];
        }
    }
    m_d->m_size = sz;
    m_d->m_str[m_d->m_size] = 0;
    std::memcpy(m_d->m_str, str, m_d->m_size);
}
 
}
Yandex
Объявления
12.08.2016, 15:55     константная ссылка в качестве аргумента конструктору копирования
Ответ Создать тему
Опции темы

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