0

这是我的代码:

class LibItem
{
public:
    virtual void PrintDetails() = 0;
    virtual void setDetails() = 0;
    void setTitle(string TitleName)
    {
        Title = TitleName;
    }
    string getTitle()
    {
        return Title;
    }
    void setReleaseDate(string date)
    {
        ReleaseDate = date;
    }
    string getReleaseDate()
    {
        return ReleaseDate;
    }
    void setAuthor(string AuthorName)
    {
        Author = AuthorName;
    }
    string getAuthor()
    {
        return Author;
    }
    void setCopyright(string CopyrightDetails)
    {
        Copyright = CopyrightDetails;
    }
    string getCopyright()
    {
        return Copyright;
    }
    void setGenre(string GenreDetails)
    {
        Genre = GenreDetails;
    }
    string getGenre()
    {
        return Genre;
    }
    void setStatus(string StatusDetails)
    {
        Status = StatusDetails;
    }
    string getStatus()
    {
        return Status;
    }
private:
    string Title;
    string ReleaseDate;
    string Author;
    string Copyright;
    string Genre;
    string Status;
};

class Book : public LibItem
{
public:
    Book(string TitleName)
    {
        setTitle(TitleName);
    }
    void setISBN(int ISBNDetails)
    {
        ISBN = ISBNDetails;
    }
    int getISBN()
    {
        return ISBN;
    }
    void setDetails(string setBookTitle, string setBookAuthor, string setBookReleaseDate, string setBookCopyright, string setBookGenre, string setBookStatus, int setBookISBN)
    {
        setTitle(setBookTitle);
        setAuthor(setBookAuthor);
        setReleaseDate(setBookReleaseDate);
        setCopyright(setBookCopyright);
        setGenre(setBookGenre);
        setStatus(setBookStatus);
        setISBN(setBookISBN);
    }
    void PrintDetails()
    {
        cout << "Title: " << getTitle() << endl;
        cout << "Author: " << getAuthor() << endl;
        cout << "Release Date: " << getReleaseDate() << endl;
        cout << "Copyrite: " << getCopyright() << endl;
        cout << "Genre: " << getGenre() << endl;
        cout << "Status: " << getStatus() << endl;
        cout << "ISBN: " << getISBN() << endl;
    }

private:
    Book();
    int ISBN;

};

class DVD : public LibItem
{
public:
    DVD(string TitleName)
    {
        setTitle(TitleName);
    }
    void setRunningTime(int RunningTimeDetails)
    {
        RunningTime = RunningTimeDetails;
    }
    int getRunningTime()
    {
        return RunningTime;
    }
    void setDirector(string DirectorDetails)
    {
        Director = DirectorDetails;
    }
    string getDirector()
    {
        return Director;
    }
    void setStudio(string StudioDetails)
    {
        Studio = StudioDetails;
    }
    string getStudio()
    {
        return Studio;
    }
    void setProducer(string ProducerDetails)
    {
        Producer = ProducerDetails;
    }
    string getProducer()
    {
        return Producer;
    }
    void setDetails(string setDVDTitle, string setDVDAuthor, string setDVDReleaseDate, string setDVDCopyright, string setDVDGenre, string setDVDStatus, int setDVDRunningTime, string setDVDDirector, string setDVDStudio, string setDVDProducer)
    {
        setTitle(setDVDTitle);
        setAuthor(setDVDAuthor);
        setReleaseDate(setDVDReleaseDate);
        setCopyright(setDVDCopyright);
        setGenre(setDVDGenre);
        setStatus(setDVDStatus);
        setDirector(setDVDDirector);
        setStudio(setDVDStudio);
        setProducer(setDVDProducer);
    }
    void PrintDetails()
    {
        cout << "Title: " << getTitle() << endl;
        cout << "Author: " << getAuthor() << endl;
        cout << "Release Date: " << getReleaseDate() << endl;
        cout << "Copyrite: " << getCopyright() << endl;
        cout << "Genre: " << getGenre() << endl;
        cout << "Status: " << getStatus() << endl;
        cout << "Running Time: " << getRunningTime() << endl;
        cout << "Director: " << getDirector() << endl;
        cout << "Studio: " << getStudio() << endl;
        cout << "Producer: " << getProducer() << endl;
    }

private:
    DVD();
    int RunningTime;
    string Director;
    string Studio;
    string Producer;

};

我在使用虚拟 void setDetails(); 时遇到问题;

我希望 Book 和 DVD 类都有一个名为 setDetails 的方法来设置详细信息。问题是,Book 类和 DVD 类对此方法都有不同的参数。

我怎样才能做到这一点?

解决这个问题的最佳方法是什么?

4

5 回答 5

0

自从

setDetails(string setDVDTitle, string setDVDAuthor, string setDVDReleaseDate, string setDVDCopyright, string setDVDGenre, string setDVDStatus, int setDVDRunningTime, string setDVDDirector, string setDVDStudio, string setDVDProducer)

仅对 DVD 对象有意义,并且

setDetails(string setBookTitle, string setBookAuthor, string setBookReleaseDate, string setBookCopyright, string setBookGenre, string setBookStatus, int setBookISBN)

只对一本书有意义,方法不应该是virtual,也不应该在基类中。

假设我给你一个LibItem*,我告诉你设置它的细节。你做什么工作?设置它的细节是否有意义,因为它们从一个具体的实现类到另一个不同?

基类应该只具有设置的方法:

string Title;
string ReleaseDate;
string Author;
string Copyright;
string Genre;
string Status;

不应该是virtual,因为它的行为不会因实现而异,您应该在实现类本身上设置具体细节。

于 2012-08-28T15:51:03.940 回答
0

抽象基类只能包含所有派生类共有的函数,所以如果在不同派生类中需要不同的函数,就不能进入基类。

您可以向下转换以获取派生类型,并访问其特定于类型的函数:

LibItem & item = some_item();

if (Book * book = dynamic_cast<Book*>(&item)) {
    book->setDetails(book_details);
} else if (DVD * dvd = dynamic_cast<DVD*>(&item)) {
    dvd->setDetails(dvd_details);
}

如果您有许多不同的类型和许多特定于类型的操作,那么可能值得考虑访问者模式;但在大多数情况下,这太过分了。

于 2012-08-28T15:54:23.787 回答
0

你不能,你需要通用接口。http://www.tutorialspoint.com/cplusplus/cpp_interfaces.htm。这篇文章对你理解抽象类有很大帮助。对于不同的孩子有不同的参数的成员函数不应该是虚拟的。

查看您的代码:

尝试将您的参数类型从“string”更改为“const string&”,您将避免复制。

于 2012-08-28T15:55:49.853 回答
0
virtual void LibItem::setDetails() = 0;

void Book::setDetails(string setBookTitle, string setBookAuthor, string setBookReleaseDate, string setBookCopyright, string setBookGenre, string setBookStatus, int setBookISBN)

void DVD::setDetails(string setDVDTitle, string setDVDAuthor, string setDVDReleaseDate, string setDVDCopyright, string setDVDGenre, string setDVDStatus, int setDVDRunningTime, string setDVDDirector, string setDVDStudio, string setDVDProducer)

是不同的方法,因此,您的代码中没有重载。

顺便提一句。不要忘记 LibItem 中的虚拟析构函数......

于 2012-08-28T15:57:41.183 回答
0

有两种方法可以处理这个问题。第一个涉及可变参数,将基中的接口声明为setDetails( std::string const& title... ). 但是,我不会进一步讨论这种方式,因为它是以后发生无法解释的崩溃的可靠途径。另一种解决方案是使用类似: 的东西setDetails( std::map< std::string, std::string > const& ),并在具体实现中按名称提取您想要的详细信息。即使这样,我也不确定这是一个好的解决方案,因为给定 a LibItem*,你不知道在地图中放什么。(如果您从用户那里获取对象的类型和详细信息列表,这可能是一个有效的解决方案。即便如此,我可能会将其封装到一个工厂函数中,该函数将知道它正在创建的类型,验证详细信息对应,然后将所有细节传递给构造函数。)

当我这样做时:你不能使用intfor ISBN。最合理的表示是字符串。

于 2012-08-28T16:10:40.573 回答