#c #oop #dynamic-memory-allocation
#c #ооп #динамическое выделение памяти
Вопрос:
я изучаю концепцию объектно-ориентированного программирования
Начал с динамического выделения памяти и нашел проблему в этом коде . Я не могу найти проблему в этом коде, на мой взгляд, все хорошо
#include <iostream>
using namespace std;
class Team
{
private:
char *name;
char stadium[20];
char city[20];
public:
Team(const char *i=" ",const char *stadium=" ",const char *city=" ")
{
name=new char [strlen(i)];
strcpy(name,i);
strcpy(this->stadium,stadium);
strcpy(this->city,city);
}
const char *getName() {
return name;
}
const char *getCity() {
return city;
}
const char *getStadium() {
return stadium;
}
void setName(char *name) {
strcpy(this->name, name);
}
~Team() {
delite [] name;
}
};
};
int main()
{
Team *e1 = new Team("Real Madrid", "Madrid", "Santiago Bernabeu");
Team *e2 = new Team(*e1);
cout << e1->getName();
cout << "-";
cout << e2->getName();
e1->setName("Barselona");
cout << e1->getName();
cout << "-";
cout << e2->getName();
delete e1;
delete e2;
return 0;
}
Я пытался решить эту проблему более 3 часов… и ничего не нашел, я знаю, что это может быть не тот способ, которым мне нужно искать решение. Но я устал пытаться это исправить.
Некоторые из ошибок, которые я получаю
main.cpp: In constructor ‘Team::Team(const char*, const char*, const char*)’:
main.cpp:13:24: error: ‘strlen’ was not declared in this scope
name=new char [strlen(*i)];
^~~~~~
main.cpp:13:24: note: suggested alternative: ‘mbrlen’
name=new char [strlen(*i)];
^~~~~~
mbrlen
main.cpp:14:9: error: ‘strcpy’ was not declared in this scope
strcpy(name,i);
^~~~~~
main.cpp:14:9: note: suggested alternative: ‘strtoq’
strcpy(name,i);
^~~~~~
strtoq
Я попробовал этот код
#include<iostream>
#include<cstring>
using namespace std;
class Team {
private:
char *name;
char city[20];
char stadion[30];
public:
Team(char *name = "", char *city = "", char *stadion = "") {
this->name = new char[20];
strcpy(this->name, name);
strcpy(this->city, city);
strcpy(this->stadion, stadion);
}
Team(const Team amp;e) {
strcpy(name, e.name);
strcpy(city, e.city);
strcpy(stadion, e.stadion);
}
const char *getName() {
return name;
}
const char *getCity() {
return city;
}
const char *getStadion() {
return stadion;
}
void setName(char *name) {
strcpy(this->name, name);
}
~Team() {
// delite [] name;
}
};
int main() {
Team *e1 = new Team("Real Madrid", "Madrid", "Santiago Bernabeu");
Team *e2 = new Team(*e1);
cout << e1->getName();
cout << "-";
cout << e2->getName();
e1->setName("Barselona");
cout << e1->getName();
cout << "-";
cout << e2->getName();
delete e1;
delete e2;
return 0;
}
И получаем эту ошибку
main.cpp:44:26: warning: ISO C forbids converting a string constant to ‘char*’ [-Wwrite-strings]
Segmentation fault (core dumped)
Комментарии:
1. Не могли бы вы добавить сообщение об ошибке и некоторую информацию о том, что вы пробовали?
2. я отредактирую сообщение сейчас, не беспокойтесь 🙂
3. Что не так с
std::string
? И если вы настаиваете на ручном выделении памяти для строк, имейте в виду, чтоstrlen(i)
(неstrlen(*i)
) не включает нулевой ограничитель. Такжеdelite [] name;
недопустим C4. исправлено, но все еще не работает, может проблема в том, что я создаю объект в динамической памяти с динамическими выделенными параметрами?
Ответ №1:
Я исправил некоторые опечатки в вашем коде, модифицировал конструктор копирования class Team
, и он отлично работает на моем компьютере.
class Team
{
private:
char* name;
char stadium[20];
char city[20];
public:
Team(const char* i = " ", const char* stadium = " ", const char* city = " ")
{
name = new char[strlen(i) 1]; // 1 for null-terminate
strcpy(name, i);
strcpy(this->stadium, stadium);
strcpy(this->city, city);
}
// allocating memory for Team::name needed, but I delegated it to above constructor.
Team(const Teamamp; e) :Team(e.name, e.stadium, e.city) {
// empty
}
const char* getName() {
return name;
}
const char* getCity() {
return city;
}
const char* getStadium() {
return stadium;
}
void setName(const char* name) { // must be const char*. Not char*!!
strcpy(this->name, name);
}
~Team() noexcept {
if(name)
delete[] name; // delete[] name, NOT delite
}
};
Вот более предпочтительный способ написания классов C .
Как уже говорилось в некоторых комментариях, предпочитаю использовать std::string
to char*
. Я знаю, что, возможно, трудно привыкнуть к классам C , но, поверьте мне, std::string
это намного лучше, чем char*
. С std::string
вам не нужно самостоятельно выделять память, и вам не требуется писать дополнительный конструктор копирования и деструктор.
#include <string>
using std::string;
class Team
{
public:
Team(void) = default;
explicit Team(const stringamp; name, const stringamp; stadium, const stringamp; city)
:name_(name), stadium_(stadium), city_(city) {}
void setName(const stringamp; new_name) { name_ = new_name; }
string getName(void) const { return name_; }
string getCity(void) const { return city_; }
string getStadium(void) const { return stadium_; }
private:
string name_;
string stadium_;
string city_;
};
Комментарии:
1. я пробовал это, но все еще не работает…
code error: ‘strlen’ was not declared in this scope name = new char[strlen(i) 1]; // 1 for null-terminate main.cpp:15:9: error: ‘strcpy’ was not declared in this scope strcpy(name, i);
2. @World Вы должны включить
<cstring>
в C , чтобы использоватьstrcpy()
иstrlen()
.3. да .. это была проблема так… Не обращайте внимания на тебя, парень с большими мозгами: D <3
4. Педантичный момент — при копировании строк в буферы символов действительно следует использовать
strncpy
илиstrcpy_s
. (стадион и город). Также, если у вас есть открытые указатели, должен быть конструктор по умолчанию для его инициализацииnullptr
или объявленияdeleted
.5. Я бы также предложил, возможно, использовать ссылки rvalue для конструктора, чтобы вы могли создать экземпляр с
char-const*
строками.
Ответ №2:
Добавьте #include <cstring>
в свой основной файл: C
#include <iostream>
using namespace std;
#include<cstring> // Add this in your code
В вашем основном файле:
int main() {
...
}