views:

87

answers:

1

I've been staring at this for a while and not getting very far. FruitBasketFactory, FruitBasket, and Fruit are three classes from an API I'm using. My goal is to make a fruit basket and then retrieve the fruit. According to the FruitBasketFactory.hpp:

const FruitBasket* getFruitBasket() const;

and then in the FruitBasket.hpp

size_t getNumFruits() const;
const Fruit& operator[](size_t index) const;

So here's my initial code:

FruitBasketFactory fruitBasketFactory;
//since I want an object rather than a pointer I attempt to dereference the pointer
const FruitBasket fruitBasket = *(fruitBasketFactory.getFruitBasket());

But here I get an error "error C2248: 'FruitBasket::FruitBasket' : cannot access private member declared in class 'FruitBasket'". Shouldn't this work?

So, fine... I rework my code.

FruitBasketFactory fruitBasketFactory;
const FruitBasket* fruitBasket = fruitBasketFactory.getFruitBasket();

if(fruitBasket->getNumFruits() > 0) {
    //using (*fruitBasket)[0] seems silly
    const Fruit fruit = (*fruitBasket)[0];
}

And fail: "error C2248: 'Fruit::Fruit' : cannot access private member declared in class 'Fruit'"

So, another rework

FruitBasketFactory fruitBasketFactory;
const FruitBasket* fruitBasket = fruitBasketFactory.getFruitBasket();

if(fruitBasket->getNumFruits() > 0) {
    //this is just ludicrous ... I'm doing something wrong
    const Fruit* fruit = &(fruitBasket->operator[](0));
}

As goofy as this piece of code looks, it actually works. But why can I just do what I think should be the most obvious thing?

FruitBasketFactory fruitBasketFactory;
const FruitBasket fruitBasket = *(fruitBasketFactory.getFruitBasket());

if(fruitBasket.getNumFruits() > 0) {
    const Fruit fruit = fruitBasket[0];
}

Resolution:

The copy constructors were indeed blocked for both FruitBasket and Fruit. I was able to get around calling them by creating references as follows:

FruitBasketFactory fruitBasketFactory;
const FruitBasket& fruitBasket = *(fruitBasketFactory.getFruitBasket());

if(fruitBasket.getNumFruits() > 0) {
    const Fruit& fruit = fruitBasket[0];
}
+1  A: 

But here I get an error error C2248: 'FruitBasket::FruitBasket' : cannot access private member declared in class 'FruitBasket'.

The copy constructor for FruitBasket is inaccessible. Have you declared the copy constructor for this class as private or protected? Does this class have any bases or members that are not copyable (i.e., that do not have publicly accessible copy constructors)?

To answer your last question, this:

const Fruit* fruit = &(fruitBasket->operator[](0));

can be much more reasonably written as this:

const Fruit* fruit = &(*fruitBasket)[0];

The pointer must be dereferenced so that the subscript operator is applied to the class-type FruitBasket object and not to the pointer to the FruitBasket.

If you apply the subscript of the pointer, the built-in subscript operator is used and the pointer is treated as a pointer to an array of FruitBasket objects.

James McNellis
OP's 'initial code' seems to indicate that your answer to his last question wouldn't work.
Forrest
@Forrest: The alternative I give is equivalent; `p->operator[](0)` is the same as `(*p)[0]` where `p` is a pointer to an object that overloads `operator[]`.
James McNellis
Good advice! I didn't understand that the copy constructors were blocked.
John Berryman