4 / 4 / 14
Регистрация: 03.03.2013
Сообщений: 55
1

Класс "вектор" с конструкторами, позволяющими создать нулевой вектор и вектор с произвольным числом элементов

06.03.2014, 00:13. Показов 7343. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет!

Задача следующая.
Нужно реализовать класс "вектор" с конструкторами, которые позволяют создать нулевой вектор и вектор с произвольным кол-во элементов. И требуется перегрузить ряд операций.

Пока что перегружены [], =, +. Но где-то ошибка и я не понимаю где.

При варианте
C++
1
CVector v3 = v2;
ошибок нет, а, если так сделать
C++
1
CVector v3 = v2 + v1;
компилятор начинает ругаться.

Вот код и вывод комплятора =)

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
30
31
32
33
#include "CVector.h"
 
#include <iostream>
using namespace std;
 
#define N 10
 
void PrintVector(char *str, CVector &obj)
{
    cout << str << " :: ";
    for (int i = 0; i < obj.GetSize(); i++)
        cout << obj[i] << " ";
    cout << endl;
}
 
int main(int argc, char *argv[])
{
    int *a = new int[N];
 
    for (int i = 0; i < N; i++)
        a[i] = i*11;
 
    CVector v1(N, a);
    PrintVector("v1", v1);
 
    CVector v2(v1);
    PrintVector("v2", v2);
 
    CVector v3 = v1 + v2;
    PrintVector("v3 = v1 + v2", v3);
 
    return 0;
}
CVector.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
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
#include "CVector.h"
 
#include <iostream>
#include <cstdlib>
using namespace std;
 
CVector::CVector(int s, int *arg)
{
    if (s <= 0) {
        cout << "Размерность вектора указана неправильно!\n";
        return;
    }
 
    size = s;
    p_vector = new int[s];
 
    for (int i = 0; i < size; i++)
        p_vector[i] = arg[i];
}
 
CVector::CVector(CVector &obj)
{
    size = obj.size;
    p_vector = new int[obj.size];
 
    for (int i = 0; i < size; i++)
        p_vector[i] = obj.p_vector[i];
}
 
void CVector::InitVector(int s, int *arg)
{
    if (p_vector) delete [] p_vector;
 
    size = s;
    p_vector = new int[s];
 
    for (int i = 0; i < size; i++)
        p_vector[i] = arg[i];
}
 
int &CVector::operator[](int i)
{
    if (i < 0 || i > (size - 1)) {
        cout << "Неверный индекс.\n";
        exit(1);
    }
 
    return p_vector[i];
}
 
CVector CVector::operator=(CVector obj)
{
    // Если размеры векторов не совпадают, то
    // выделяется память нужного размера
    if (size != obj.size) {
        delete [] p_vector;
        p_vector = new int[obj.size];
        size = obj.size;
    }
 
    for (int i = 0; i < size; i++)
        p_vector[i] = obj.p_vector[i];
 
    return *this;        
}
 
CVector CVector::operator+(CVector obj)
{
    CVector tmp = *this;
 
    if (tmp.size == obj.size) {
        for (int i = 0; i < tmp.size; i++)
            tmp.p_vector[i] += obj.p_vector[i];
    } else {
        cout << "Вектора разной размерности." << endl;
        exit(1);
    }
 
    return tmp;
}
CVector.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class CVector
{
    int *p_vector;
    int size;
 
public:
    CVector() { size = 0; p_vector = 0; }
    CVector(int s, int *arg);
    CVector(CVector &obj);
    ~CVector() { if (p_vector) delete [] p_vector; }
 
    void InitVector(int s, int *arg);
    int GetSize() { return size; }
 
    int &operator[](int i);
    CVector operator=(CVector obj);
    CVector operator+(CVector obj);
};
Bash
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
main.cpp: In function ‘int main(int, char**)’:
main.cpp:24:25: warning: deprecated conversion from string constant to ‘char*[-Wwrite-strings]
     PrintVector("v1", v1);
                         ^
main.cpp:27:25: warning: deprecated conversion from string constant to ‘char*[-Wwrite-strings]
     PrintVector("v2", v2);
                         ^
main.cpp:29:23: error: no matching function for call to ‘CVector::CVector(CVector)’
     CVector v3 = v1 + v2;
                       ^
main.cpp:29:23: note: candidates are:
In file included from main.cpp:1:0:
CVector.h:9:5: note: CVector::CVector(CVector&)
     CVector(CVector &obj);
     ^
CVector.h:9:5: note:   no known conversion for argument 1 from ‘CVector’ to ‘CVector&’
CVector.h:8:5: note: CVector::CVector(int, int*)
     CVector(int s, int *arg);
     ^
CVector.h:8:5: note:   candidate expects 2 arguments, 1 provided
CVector.h:7:5: note: CVector::CVector()
     CVector() { size = 0; p_vector = 0; }
     ^
CVector.h:7:5: note:   candidate expects 0 arguments, 1 provided
main.cpp:30:35: warning: deprecated conversion from string constant to ‘char*[-Wwrite-strings]
     PrintVector("v3 = v1 + v2", v3);
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.03.2014, 00:13
Ответы с готовыми решениями:

Создать класс вектор с несколькими конструкторами
&quot;Написать класс булев вектор. Класс должен содержать несколько конструкторов. Сделать методы вывода...

Создать класс «Вектор в трехмерном пространстве» позволяющий вычислять сумму векторов, их разность и произведение вектор
Доброго времени суток зашедшим помочь. Создать класс «Вектор в трехмерном пространстве»...

Создать клас ВЕКТОР целых чисел. Разработать класс СТЕК, который вмещает объект класса ВЕКТОР
Создать клас ВЕКТОР целых чисел. Разработать класс СТЕК, который вмещает объект класса ВЕКТОР....

Матрица и вектор. Создать вектор, содержащий количество отрицательных элементов каждого столбца
Создать вектор М, т.е. одно мерный массив, содержащий количество отрицательных элементов каждого...

Дан целочисленный вектор А(12), среди его элементов есть одинаковые. Создать вектор В из различных элементов вектора А
Дан целочисленный вектор А(12), среди его элементов есть одинаковые. Создать вектор В из различных...

5
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
06.03.2014, 00:25 2
пока не придумал почему там при конверсии какие-то неоднозначности, но решение может быть таким:
сигнатуры функций нужно подправить. если функция работает с толстым объектом и не модифицирует его,
то желательно его передавать по константной ссылке (если нет мува по крайней мере):
CVector(const CVector &obj);
CVector& operator=(const CVector& obj);
CVector operator+(const CVector& obj) const;
1
4 / 4 / 14
Регистрация: 03.03.2013
Сообщений: 55
06.03.2014, 22:46  [ТС] 3
Помогло, спасибо большое!

Если поймете как объяснить возникающую неоднозначность, то с удовольствием послушаю.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
07.03.2014, 00:04 4
После изменений какие предупреждения выдаёт?
Тут тоже следует подправить: void PrintVector( const char * str, CVector & obj )
1
19252 / 10009 / 2436
Регистрация: 30.01.2014
Сообщений: 17,646
07.03.2014, 00:12 5
warning: deprecated conversion from string constant to ‘char*’
Означает, неявное преобразование из константного массива символов к указателю на неконстантный массив символов объявлено запрещенным к использованию. Это логично. Ибо через такой указатель можно будет поменять константную строку, что приведет UB (undefined behaviour, google it).
error: no matching function for call to ‘CVector::CVector(CVector)’
CVector v3 = v1 + v2;
Операция сложения создает временный объект. Временный объект - это rvalue (google it). Преобразование rvalue к неконстантной ссылке запрещено, поэтому он пытается найти конструктор, который принимает вектор по значению, но не находит - отсюда ошибка.
no known conversion for argument 1 from ‘CVector’ to ‘CVector&’
Говорит как раз о запрете, который я озвучил выше.

Советы:
там, где вектор не изменяется - его следует передавать по константной ссылке.
методы, которые не изменяют состояние объекта вектора, следует помечать как const (в примере DU это есть).
функция exit крайне не рекомендуется к использованию в программах на С++, т.к. выход из программы игнорирует все конструкторы уже созданных объектов, что может приводить к утечкам ресурсов (для спорщиков: да, я знаю, что память отдается системе после выхода, но память не единственный ресурс).
для operator[] принято реализовывать две версии, неконстантную и константную (не позволяет менять объекты внутри вектора, только читать).

Есть еще замечания, но по сравнению с озвученным - это уже придирки.
1
4 / 4 / 14
Регистрация: 03.03.2013
Сообщений: 55
07.03.2014, 01:21  [ТС] 6
castaway, если подправить PrintVector, тоже больше никаких предупреждений не выводится.

DrOffset, с UB и rvalue более менее понятно. С exit - тоже.

Всем большое спасибо!
0
07.03.2014, 01:21
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.03.2014, 01:21
Помогаю со студенческими работами здесь

Класс вектор с конструкторами и операциями
День добрый! Очень прошу помочь хотя бы понять задание и что мне требуется сделать (с++ не изучал,...

Создать класс, полями есть динамический вектор(то есть указатель на вектор) его размер и идентификатор
Задание нужно создать класс, полями есть динамический вектор(то есть указатель на вектор) его...

Матрицу [3][4] из матрицы сформировать вектор первые элементы это первый ряд и тд вектор отсортировать вектор по >
вектор создал только не могу отсортировать вектор выводит непонятные числа Вот код: #include...

Дан вектор А. Получить новый вектор,состоящий из квадратов отрицательных компонентов. Упорядочить вектор в порядке возрастания значений
Помогите составить блок-схему и программу к ней на паскале abc.Пожалуйста! Очень срочно....Условие...

Базовый класс вектор на плоскости, производный класс вектор в пространстве
Товарищи программисты! Прошу у вас помощи с этими задачами. Сам в программировании не понимаю, но...

Создать иерархию классов вектор и безопасный вектор с проверкой выхода за пределы
Создать иерархию классов вектор и безопасный вектор с проверкой выхода за пределы. Безопасный...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru