Reputation:
Observe the following interface/implementation:
properties.h
class Property
{
public:
Property(PropertyCollection * propertyCollection, std::string key,
std::string value, uint32_t identifier);
properties.cpp
Property::Property(PropertyCollection * propertyCollection,
std::string key, std::string value, uint32_t identifier = 0)
: propertyCollection(propertyCollection), key(key), value(value),
identifier(identifier) {}
As you can see, I have a default initializer for the last argument.
However, I still get this Eclipse error:
main.cpp
Properties properties (*file);
Property property (&properties, std::string("Cats"), std::string("Rule"));
no matching function for call to ‘Property::Property(Properties*, std::string, std::string)’
EDIT: Properties
inherits from PropertyCollection
. PropertyCollection
is a pure virtual class.
+----------------------+
| <<pure virtual>> |
| PropertyCollection |
+----------------------+
| |
+----------------------+
^
|
+
+-----------------------+
| Properties |
|-----------------------|
| |
+-----------------------+
In Java I'd think of Properties
*as a * PropertyCollection
and just pass the reference as-is. However, in C++, must I cast the pointer to the base class somehow?
Edit: Guess not. The sole problem was the location of the default initializer.
Upvotes: 4
Views: 68
Reputation: 206607
The solution has already provided in a the answer by juanchopanza. I'm going to present how the .h file and the .cpp file should look after the change.
properties.h
class Property
{
public:
Property(PropertyCollection * propertyCollection, std::string key,
std::string value, uint32_t identifier = 0);
properties.cpp
Property::Property(PropertyCollection * propertyCollection,
std::string key, std::string value, uint32_t identifier)
: propertyCollection(propertyCollection), key(key), value(value),
identifier(identifier) {}
Upvotes: 1
Reputation: 227418
You need to put the default parameter in the member function declaration, i.e. in the header file, not in its definition:
class Property
{
public:
Property(PropertyCollection * propertyCollection, std::string key,
std::string value, uint32_t identifier = 0);
In the code you've shown, main
can only see Property::Property(PropertyCollection*, std::string, std::string, uint32_t)
.
Upvotes: 1
Reputation: 63797
The why
It seems as if you are including properties.h
from your main source code and later link against what is inside properties.cpp
, which is totally fine in trivial cases.
But when doing what you are doing there's no way for the compiler to know (at time of compiling main) that the constructor you are trying to invoke has a default parameter (this isn't know until you are linking against properties.cpp
).
In main the compiler only knows what you have told it, more specifically it only knows about
Property::Property (PropertyCollection * propertyCollection, std::string key,
std::string value, uint32_t identifier);
The solution
The simple, and recommended, solution is to move the default-value specification to the constructor declaration in properties.h
, this way the compiler will have all the information required to make things work the way you intend.
Upvotes: 4
Reputation: 8805
In the constructor:
Property(PropertyCollection * propertyCollection, std::string key, std::string value);
Your constructor:
Property(Property * propertyCollection, std::string key, std::string value);
Pass an address of an object of PropertyCollection
, or create new constructor.
Upvotes: 0