在类中使用构造函数初始化指针

3

我有一个在 "album.h" 中的 Album 类,代码如下:

#include "song.h"

class Album
{
public:
Album(string _id, string _title, string _singer, float _price, vector<Song> _songs) : id(_id), title(_title), singer(_singer), price(_price), songs(_songs), availableAlbums(10) {}
void add_song(Song s){ songs.push_back(s); }
void add_availableAlbums(int added){ availableAlbums += added; }
string get_id(){ return id; }
string get_singer(){return singer;}

private:
string id;
string title;
string singer;
float price;
vector <Song> songs;
int availableAlbums;
};

还有一个在 "song.h" 文件中的 Song 类,如下所示:

#include "album.h"

class Song
{
public:
Song(string _numOfSong, string _title, string _singer, string _duration, float _price): 
numOfSong(_numOfSong), title(_title), singer(_singer), duration(_duration), price(_price){}

private:
string numOfSong;
string title;
string singer;
string duration;
float price;
Album* album;
};

我们知道每首歌都有一个专辑(每首歌必须指向它的专辑),我通过为每首歌初始化一个专辑*来实现这一点,但我遇到了一些错误,这些错误在此处:
error C2061: syntax error : identifier 'Album'
error C2065: '_album' : undeclared identifier
error C2143: syntax error : missing ';' before '*'
error C2614: 'Song' : illegal member initialization: 'album' is not a base or member
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

thanks


我不确定我看到问题在哪里。试试这个。虽然我会为此使用智能指针。 - drescherjm
2
“如何使每首歌都指向其专辑?” 取决于您在类“Album”中实例化“Song”实例的方式,最有可能的是您在那里传递了一个“this”指针。 - πάντα ῥεῖ
1
在Song.h类声明之前,使用class Album;进行Album的前向声明。 - drescherjm
@mama23n 现在(使用更新的代码)你有一个循环包含。同时,你没有使用包含保护。 - drescherjm
1
https://dev59.com/G3RB5IYBdhLWcg3wbGxB - drescherjm
2个回答

9

Your Song class has an constructor that takes a pointer to the Album class so assume that you have the following code:

Album* album = new Album();
Song song = new Song(album);

In the first line you create a new album and in the second line you create a new song with the recently created album.

Album* album1 = song->album; // This is how you can access song's album

But, be aware that whenever you use new to create an object you should use delete keyword when you finished working with that object to free the memory used for that object.

So, there is no problem in your code or at least I can't find any.


努力不错,但我绝不建议使用newdelete,而是改用shared_ptrmake_shared或它们的unique等效方法。 - John Dibling
是的,你说得对,但我想知道如何将专辑传递给构造函数,因为 Song 类的第四行出现了错误,我不知道那是什么。 - mama23n
1
@mama23n 如果您没有提供足够的信息,我们无法帮助您,请告诉我们您遇到了什么错误。 - Shahriyar
@Shahriyar 我这么做 - mama23n

1
代码是正确的,你只需确保在 Song 实例的生命周期内存在 Album 实例。 如果 Song::album 指针不会被更改,使用引用可能更加清晰。这意味着在构造后无法将 album 指向另一个专辑。
class Song {
public:
    Song(Album& _album) : album(_album) { }
private:
    Album& album;
}

但是默认的operator=不能赋值给Song。需要重载它来检查另一个Song的专辑是否相同,并且只分配其他属性。

如果Song不修改Album对象,则可以通过将const Album*(或const Album&)用作成员变量类型和构造参数来强制执行const-correctness。

如果Album对象的生命周期未经手动控制,则可以使用std::shared_ptr<Album>


但是在Song类的第四行(在Song构造函数中)存在错误,我不知道该怎么办... - mama23n
@mama23n 是什么错误?请编辑您的问题,包括您遇到的确切错误以及一些上下文。根据您提供的信息,我们必须玩一个猜测问题的游戏。 - drescherjm
@drescherjm 我会做那个。 - mama23n
修正了此回复中的错误。 - tmlen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接