2

<< 演算子の基本的なオーバーロードを書いているので、クラス インターフェイス内にフレンド関数を追加しました。

namespace Warehouse
{
namespace Dto
{
    class Product;

    class AbstractOrder : public ICloneableItem
    {
      protected:
        unsigned long _id;
        std::string _name;
        std::vector<Product*> _products;

      public:
        AbstractOrder();
        virtual ~AbstractOrder();

        double computePrice() const;

        void addProduct(Product* product);
        void removeProduct(Product* product);
        void removeAllProducts();

        void setName(const std::string& name) { _name = name; }
        std::string getName() const { return _name; }

        unsigned long getId() const { return _id; }
        std::vector<Product*> getProductList() const { return _products; }

        friend std::ostream& operator<<(std::ostream& os, const AbstractOrder& ord);
    };
}
}

実装ファイル内では、これは関数のコードです

using namespace Warehouse::Dto;
....

std::ostream& operator<<(std::ostream& os, const AbstractOrder& ord) 
{
os << "[" << ord._id << "] Order " << ord._name << ": " << ord.computePrice();
return os;
}

次のエラーが表示されるのはなぜですか? エラー 1 エラー C2248: 'Warehouse::Dto::AbstractOrder::_id': クラス 'Warehouse::Dto::AbstractOrder' で宣言された保護されたメンバーにアクセスできません

実際には、実装ファイルの operator<< の前に名前空間を追加して、既に修正しています。理解できないのは、実装ファイルでusing namespace Warehouse::Dtoディレクティブを使用している場合でも、なぜそれをしなければならないのかということです。

4

1 に答える 1

2

operator <<はグローバル名前空間で定義されており、AbstractOrderクラスは名前空間で定義されているためWarehouse::Dtoです。しかし、friend 宣言は、Warehouse::Dto名前空間のストリーム オペレーター用です。

グローバル名前空間でオペレーターの適切なフレンド宣言を定義する場合は、次のようになります。

friend std::ostream& ::operator<<(std::ostream& os, const AbstractOrder& ord);

ただし、オペレーターがストリーミングしているクラスと同じ名前空間にオペレーターを配置する必要があります。

于 2013-04-02T13:19:14.177 に答える