我正在学习在C ++中动态分配内存。我遇到了一个我似乎无法找到答案的问题。
在我的计划中,我有一个struct
,如下所示:
struct Friend
{
string name = "";
int daysSinceContact = 0;
};
struct User
{
string name = "";
string password = "";
int numberOfFriends = 0;
Friend *friends = new Friend[numberOfFriends];
};
在我的程序中,我创建了一个用户数组,如下所示:
int numberOfUsers = 5;
User *usersInformation = new User[numberOfUsers];
它工作正常。但我希望能够为所选用户添加更多朋友,例如:
int nFriends = usersInformation[0].numberOfFriends;
usersInformation[0].numberOfFriends++;
usersInformation[0].friends[nFriends-1].name = "John";
usersInformation[0].friends[nFriends-1].daysSinceContact = 2;
我猜我应该使用缓冲区来复制包含朋友信息的数组中的信息,并执行以下操作:
delete[] usersInformation[0].friends[];
usersInformation[0].numberOfFriends++;
usersInformation[0].friends = new Friend[numberOfFriends];
然后将其复制回来并添加有关新朋友的信息。但是当我尝试过时,它没有用。
你有任何提示吗?
答案 0 :(得分:1)
正确的解决方案是根本不使用手动数组,而是使用STL的std::vector
容器,例如:
#include <vector>
#include <string>
struct Friend
{
std::string name = "";
int daysSinceContact = 0;
};
struct User
{
std::string name = "";
std::string password = "";
std::vector<Friend> friends;
};
...
std::vector<User> usersInformation(5);
...
Friend newFriend;
newFriend.name = "John";
newFriend.daysSinceContact = 2;
usersInformation[0].friends.push_back(newFriend);
// Or simpler:
usersInformation[0].friends.emplace_back(Friend{"John", 2});
话虽这么说,如果你真的想手动管理数组,你需要做更像这样的事情(包括实现Rule of Five以防止破坏和泄漏内存):
#include <string>
struct Friend
{
std::string name = "";
int daysSinceContact = 0;
};
struct User
{
std::string name = "";
std::string password = "";
int numberOfFriends = 0;
Friend *friends = new Friend[numberOfFriends];
// default constructor (nothing extra that isn't already done above)
User() = default;
// copy constructor
User(const User &src) :
name(src.name),
password(src.password),
numberOfFriends(src.numberOfFriends),
friends(new Friend[numberOfFriends])
{
for(int i = 0; i < numberOfFriends; ++i)
friends[i] = src.friends[i];
}
// move constructor
User(User &&src) :
name(std::move(src.name)),
password(std::move(src.password)),
numberOfFriends(numberOfFriends),
friends(src.friends)
{
src.friends = nullptr;
src.numberOfFriends = 0;
}
// destructor
~User()
{
delete[] friends;
}
// copy assignment operator
User& operator=(const User &src)
{
if (this != &src)
{
Friend *newFriends = new Friend[src.numberOfFriends];
for(int i = 0; i < src.numberOfFriends; ++i)
newFriends[i] = src.friends[i];
name = src.name;
password = src.password;
delete[] friends;
friends = newFriends;
numberOfFriends = src.numberOfFriends;
}
return *this;
}
// move assignment operator
User& operator=(User &&src)
{
name := std::move(src.name);
password = std::move(src.password);
Friend *oldFriends = friends;
friends = src.friends;
src.friends = oldFriends;
int oldNumber = numberOfFriends;
numberOfFriends = src.numberOfFriends;
src.numberOfFriends = oldNumber;
return *this;
}
// addition helper
void addFriend(const std::string &name, int daysSinceContact = 0)
{
Friend *newFriends = new Friend[numberOfFriends + 1];
for(int i < 0; i < numberOfFriends; ++i)
newFriends[i] = friends[i];
newFriends[numberOfFriends].name = name;
newFriends[numberOfFriends].daysSinceContact = daysSinceContact;
delete[] friends;
friends = newFriends;
++numberOfFriends;
}
};
或者这个,在内存管理方面稍微安全一些:
#include <string>
#include <utility>
#include <algorithm>
struct Friend
{
std::string name = "";
int daysSinceContact = 0;
};
struct User
{
std::string name = "";
std::string password = "";
int numberOfFriends = 0;
Friend *friends = new Friend[numberOfFriends];
// default constructor (nothing extra that isn't already done above)
User() = default;
// initializing constructor
User(int initialCapacity) :
friends(new Friend[initialCapacity])
{
}
// copy constructor
User(const User &src) :
User(src.numberOfFriends),
name(src.name),
password(src.password),
numberOfFriends(src.numberOfFriends)
{
std::copy(src.friends, src.friends + src.numberOfFriends, friends);
}
// move constructor
User(User &&src) :
name(std::move(src.name)),
password(std::move(src.password)),
numberOfFriends(0),
friends(nullptr)
{
std::swap(friends, src.friends);
std::swap(numberOfFriends, src.numberOfFriends);
}
// destructor
~User()
{
delete[] friends;
}
// copy assignment operator
User& operator=(const User &src)
{
if (this != &src)
User(src).swap(*this);
return *this;
}
// move assignment operator
User& operator=(User &&src)
{
src.swap(*this);
return *this;
}
// swap helper
void swap(User &other)
{
std::swap(name, other.name);
std::swap(password, other.password);
std::swap(numberOfFriends, other.numberOfFriends);
std::swap(friends, other.friends);
}
// addition helper
void addFriend(const std::string &name, int daysSinceContact = 0)
{
User temp(numberOfFriends + 1);
std::copy(friends, friends + numberOfFriends, temp.friends);
temp.friends[numberOfFriends] = Friend{name, daysSinceContact};
std::swap(friends, temp.friends);
++numberOfFriends;
}
};
无论哪种方式,你都可以这样做:
User *usersInformation = new User[5];
...
usersInformation[0].addFriend("John", 2);
...
delete[] usersInformation;