Error: Conversion to non-scalar type requested

When I try to declare a food array now in my main.cpp, I get the following two errors:

  • main.cpp|45|error: conversion from ‘Apple*’ to non-scalar type ‘Apple’ requested
  • main.cpp|11|error: invalid abstract type ‘Food’ for ‘food’

My code is as follow:

Food food[1];

Apple apple = new Apple();
food[0] = apple;
1 Like

In C# all classes are references, which means that under the hood they are actually closer to what C++ would term pointers.

So in this case, you need to be using pointers:

Food * food[1];

Apple * apple = new Apple();
food[0] = apple;

Please bear in mind that if you want to use new to dynamically allocate pointers then you need to remember to delete the object afterwards when it’s no longer needed.


If you want behaviour that’s closer to C# then you could use some of the smart pointer types introduced in C++. The one that’s most similar to how C# handles object references is the std::shared_ptr, which automatically deallocates the object when the last std::shared_ptr that refers to it is destroyed (i.e. it uses a technique called reference counting).

#include <memory>

std::shared_ptr<Food> food[1];

std::shared_ptr<Apple> apple = std::make_shared<Apple>();
food[0] = apple;

Edit:
When I say ‘destroyed’ here, I mean when it goes out of scope or gets overwritten.
So for std::shared_ptr, when you’re done with it, you have to do what you would in C# and nullify it by assigning nullptr to it.
E.g.

food[0] = nullptr;

If you use std::shared_ptr then you don’t need to use new or delete and only have to worry about assigning nullptr in the same cases that you would in C#. Hence this approach may be more familiar to you.

Be warned though that this approach does come with some additional overhead, as do virtual functions and polymorphism, so it can sometimes be worth finding alternative approaches.


Be aware that when using either raw pointers or smart pointers, you must use -> instead of . to access elements.
E.g.

std::uint32_t price = food[0]->price;

(It took me a moment to realise this was a different problem so I had to move it twice. I’m migrating these questions to separate topics so they’re easier for other people to find if they get the same problem.)

3 Likes

For future reference, a different title will help a lot.

What would you suggest, the other error “conversion from ‘Apple*’ to non-scalar type ‘Apple’ requested”?

"Problems with new" isn’t exactly precise, and "How do I use new" wouldn’t be suitable because this doesn’t explain what new actually does.

Maybe “C# reference types in C++” would be closer?

I’ll keep the code error “Invalid abstract type” and add " How to use Class with SubClass". Otherwise missing the source problem make the answer out of scope.

The answer doesn’t really explain how to do that.

The solution does specifically explain how to solve the “conversion from ‘X*’ to non-scalar type ‘X’ requested” error (which comes from Apple apple = new Apple(); attempting to turn a pointer into a scalar, which is what Apple * apple = new Apple(); fixes).

The other error only exists because Food is (presumably) an abstract type (i.e. it has a pure virtual function), which is less likely to crop up than the former.

So I think “Error: Conversion to non-scalar type requested” would be more likely to get hits.

You said it. I agree.

Consider it done.

1 Like

4 posts were split to a new topic: Dynamic arrays?