0

デフォルト以外のコンストラクターで、渡されたオブジェクト ポインターをどのように処理すればよいかわかりません。自分が何をしているのかわからないように感じるので、私はこのプログラムを間違ってやっています。

私はこれに1日半立ち往生していますが、理解できません。デフォルトのコンストラクターと非デフォルトのコンストラクターを使用する必要がある宿題の大部分を投稿します。変数/クラス/メソッドがどのように機能するかを確認できるように、使用しているクラス図も含めます。

デフォルト以外のコンストラクター内で渡されたポインターをどうすればよいですか? アクセスできないことが通知されるため、ここで値を割り当てることはできません。このコードでは:

Book::Book(string title, Author *pAuthor, Publisher *pPublisher, double price)
    {
        setTitle(title);
        setPrice(price);
    }

これらのポインターを使用する方法はありますか? 現在、デフォルトのコンストラクターを使用してすべてを正しく渡すことができますが、追加のオブジェクトを使用しているため、おそらくこれは間違っています。基本的に and で 2 行にするべきではありませんがAuthor author;Publisher publisher;この時点では気にしません。

助けてください!

Book.cpp ファイル

#include <iostream>
#include <sstream>
using namespace std;

#include "Book.h"
#include "Publisher.h"
#include "Author.h"

class Book
{
    public:
        Book();
        Book(string title, Author *pAuthor, Publisher *pPublisher, double price);
        ~Book();
        void setTitle(string title);
        void setAuthorName(string first, string last);
        void setPublisher(string name, string address, string city);
        void setPrice(double price);
        string convertDoubleToString(double number);
        string getBookInfo();

    private:
        string title;
        double price;
        Author *pAuthor;
        Publisher *pPublisher;

    Author author;
    Publisher publisher;
};

Book::Book()
{
}

Book::Book(string title, Author *pAuthor, Publisher *pPublisher, double price)
{
    setTitle(title);
    setPrice(price);
}

Book::~Book()
{
}

void Book::setTitle(string  title)
{
    this->title = title;
}

void Book::setAuthorName(string first, string last)
{
    author.setFirstName(first);
    author.setLastName(last);
}

void Book::setPublisher(string name, string address, string city)
{
    publisher.setName(name);
    publisher.setAddress(address);
    publisher.setCity(city);
}

void Book::setPrice(double price)
{
    this->price = price;
}

string Book::convertDoubleToString(double number)
{
    return static_cast<ostringstream*>( &(ostringstream() << number) ) -> str();
}

string Book::getBookInfo()
{
    return title + "\n" + author.getFullName() + "\n" + publisher.getPublisherInfo() + "\n" + "$" + convertDoubleToString(price);
}

Main.cpp ファイル:

#include <iostream>
#include <string>
using namespace std;

#include "Book.h"

int main()
{
    system("cls");

    cout << "Book 1" << endl;

    Author *pAuthor = new Author("John", "Doe");
    Publisher *pPublisher = new Publisher("Wrox", "10475 Crosspoint Blvd.", "Indianapolis");
    Book *pBook = new Book("Memory Management", pAuthor, pPublisher, 39.99);

    cout << pBook->getBookInfo() << endl;

    cout << endl << "Book 2" << endl;

    Book book;

    book.setTitle("Advanced C++ Programming");
    book.setAuthorName("Linda", "Smith");
    book.setPublisher("Microsoft Press", "One Microsoft Way", "Redmond");
    book.setPrice(49.99);

    cout << book.getBookInfo() << endl << endl;

    system("pause");

    return 0;
};

Author.cpp ファイル:

#include <iostream>
#include <string>
using namespace std;

class Author
{
    public:
        Author();
        Author(string first, string last);
        string getFullName();
        void setFirstName(string first);
        void setLastName(string last);

    private:
        string firstName;
        string lastName;
};

Author::Author()
{
}

Author::Author(string first, string last)
{
    setFirstName(first);
    setLastName(last);
}

string Author::getFullName()
{
    return firstName + " " + lastName;
}

void Author::setFirstName(string first)
{
    this->firstName = first;
}

void Author::setLastName(string last)
{
    this->lastName = last;
}

クラス図:

ここに画像の説明を入力

4

3 に答える 3

1

クラスメートと数分話し合った後、重要なコード行がいくつか欠けていることに気付きました。

私の質問の問題は、私がどのようにポインタを持っているべきかを理解していないことだったと思います。教授やクラスメートからのいくつかのヒントの後、デフォルトおよびデフォルト以外のコンストラクター内で数行のコードが欠落していることに気付きました。

ここで、私がまさに探していたものを示します。

Main.cppファイル:

#include <iostream>
#include <string>
using namespace std;

#include "Book.h"

int main()
{
    system("cls");

    cout << "Book 1" << endl;

    Author *pAuthor = new Author("John", "Doe");
    Publisher *pPublisher = new Publisher("Wrox", "10475 Crosspoint Blvd.", "Indianapolis");
    Book *pBook = new Book("Memory Management", pAuthor, pPublisher, 39.99);

    cout << pBook->getBookInfo() << endl;

    cout << endl << "Book 2" << endl;

    Book *book = new Book();

    book->setTitle("Advanced C++ Programming");
    book->setAuthorName("Linda", "Smith");
    book->setPublisher("Microsoft Press", "One Microsoft Way", "Redmond");
    book->setPrice(49.99);

    cout << book->getBookInfo() << endl << endl;

    system("pause");

    return 0;
};

Book.cppファイル:

#include <iostream>
#include <sstream>
using namespace std;

#include "Book.h"

Book::Book()
{
    pAuthor = new Author();
    pPublisher = new Publisher();
}

Book::Book(string title, Author* pAuthor, Publisher* pPublisher, double price)
{
    this->title = title;
    this->price = price;

    this->pPublisher = pPublisher;
    this->pAuthor = pAuthor;
}

Book::~Book()
{
    delete pAuthor;
    delete pPublisher;
}

void Book::setTitle(string  title)
{
    this->title = title;
}

void Book::setAuthorName(string first, string last)
{
    pAuthor->setFirstName(first);
    pAuthor->setLastName(last);
}

void Book::setPublisher(string name, string address, string city)
{
    pPublisher->setName(name);
    pPublisher->setAddress(address);
    pPublisher->setCity(city);
}

void Book::setPrice(double price)
{
    this->price = price;
}

string Book::convertDoubleToString(double number)
{
    return static_cast<ostringstream*>( &(ostringstream() << number) ) -> str();
}

string Book::getBookInfo()
{
    return title + "\n" + pAuthor->getFullName() + "\n" + pPublisher->getPublisherInfo() + "\n" + "$" + convertDoubleToString(price);
}
于 2012-09-06T01:00:14.320 に答える
1

ポインターを介して渡されるデータを保持するのに十分なメモリをポインター メンバーに割り当て、渡されたポインターが指すデータをメンバー ポインター変数にコピーする必要があります。

つまり、渡されたポインター メンバーのディープ コピーを実行する必要があります。そのため、ポインター メンバーは、それらが指すデータを所有します。

編集:
あなたが投稿したソウルションは機能しているように見えるかもしれませんが、まだ問題があります:

Book::Book() 
{     
    pAuthor = new Author();     
    pPublisher = new Publisher(); 
} 

クラス ポインター メンバーにメモリを動的に割り当てます。クラスはこれらのメンバーの有効期間を所有および制御する必要があるため、実際には独自のメモリ割り当てが必要です。Member Initializer Lists をご覧ください。ただし、4 つのパラメーターを受け取るクラスのパラメーター化されたコンストラクターは、まだメモリを割り当てません。渡されたポインター の浅いコピーを引き続き実行します。
Book

シャローコピーとは?

シャロー コピーとは、単純にポインターを特定のアドレスに向けることに他なりません。つまり、あなたのポインターが、指摘されたオブジェクトを単独で制御しているわけではないことを意味しますあなたが持っているのは、もう存在しない何かを指しているポインター、別名ダングリングポインターです。

これはあなたがするとき何が起こるかです:

Book::Book(string title, Author* pAuthor, Publisher* pPublisher, double price) 
{
    ....
    this->pPublisher = pPublisher;           
    this->pAuthor = pAuthor;     
    ....
}

この状況を回避するために必要なのはDeep Copyです。

ディープコピーとは?

ディープコピーとは、ポインタを別のメモリに割り当ててから、別のポインタの内容を独自のオブジェクトのメモリにコピーすることを意味します(浅いコピーとは異なります)。これにより、ポインタが指すオブジェクトの有効期間がポインタの有効期間とは別に分離されますそれが作成されました。

これを行うには、別のメモリをポインター メンバーに割り当ててから、クラスのオーバーロードされた=演算子に割り当て、それぞれのクラスの各メンバーをコピーする必要がありますAuthor。これを C++ で正しく実装する方法については、 copy and swap idiomPublisherを参照してください。

于 2012-09-04T05:04:51.620 に答える