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 &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)
解决方案
我更正了您代码中的一些拼写错误,修改了 的复制构造函数class Team
,它在我的 PC 上运行良好。
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 Team& 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 string& name, const string& stadium, const string& city)
:name_(name), stadium_(stadium), city_(city) {}
void setName(const string& 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_;
};
推荐阅读
- acumatica - Acumatica - 以编程方式向 AP 账单和 AR 发票添加注释
- r - R - 如何删除重复项*而不*保留单个重复行?
- java - Spring MVC:表单验证的集中处理
- hp-uft - 如何从 UFT 中的字段中检索数字?
- php - CodeIgniter 3.1.10:无法通过 DSN 使用 ODBC 连接到远程数据库
- c# - 自定义类的 C# Bizarre Object Reference Not Set 错误
- c++ - scanf() 只取数组的第一个整数
- python-3.x - 将字典的字符串表示解析为字典
- sql - 如何获取活动 SQL Server 的路径
- javascript - jQuery 显示/隐藏所需的密码字段