Reputation: 87
I'm having trouble with passing a pointer to a function that is called by another pointer. I'm trying to modify a pointer (i.e. p1) that calls the function min (i.e. p1->min()) which takes a pointer as a parameter (i.e. p1->min(*p2)). Note: *p2 isn't modified at all, just passed for its values, for which p1 will be modified based on the values of p2.
Note: I removed irrelevant code (only inside functions, everything else is as is) to make it easier to read.
Test.h
// Don't worry about the create method, just assume it works
// I'm having issues with the "min" function, more details below
class Test {
protected:
std::vector<std::vector<std::string> > vec;
public:
static Test *create(std::string file); // instantiates vec
void *min(Test *); // modifies vec
};
Test.cc
// Don't worry about create (factory method), just assume it works
// "min" is causing compiler errors (see below)
Test *Test::create(string file) { /* instantiates vec with file contents */ }
void *Test::min(const Test *&p) { /* modifies vec */ }
main.cc
// Main cannot change, this is how it must be implemented
// However, Test.cc and Test.h CAN be modified.
Test *p1 = Test::create("file1");
Test *p2 = Test::create("file2");
p1->min(*p2); // modify p1 based on values of p2, p2 is NOT modified
Compiler Errors:
fatal error: control reaches end of non-void function
What is weird is that its declared void but expecting a return value So, when I do return something it shows up another compiler error
fatal error: no viable conversion from return value of type 'Test' to function return type 'void *'
I'm so confused on the compile errors. I'm thinking it has something to do with my declarations. Note: There is no constructor since the base class must use a factory method while the derived classes use their own constructors, hence the *Test::create and *Test::min.
Please help.
Upvotes: 0
Views: 67
Reputation: 385104
What is weird is that its declared void
No, it isn't.
Test *Test::create(string file) { /* instantiates vec with file contents */ }
// ^^^^^^ return type is Test*
void *Test::min(const Test *&p) { /* modifies vec */ }
// ^^^^^^ return type is void*
It's unfortunate that you use right-aligned asterisks and ampersands, because it has directly led to your confusion. It looks like you forgot the *
was there, or thought it was part of the syntax of the function declaration itself (like how, in your question, you've referred to the functions as "*Test::create
and *Test::min
").
If you start aligning them to the left (which won't affect the program's semantics, it's just style), your intent and the meaning of types will be clear:
Test* Test::create(string file) { /* instantiates vec with file contents */ }
void* Test::min(const Test*& p) { /* modifies vec */ }
Now you can easily see at a glance that your return type isn't what you thought it was, and can correct the declaration of Test::min
(and, possibly, Test::create
).
Some people will start going on about how the internal grammar binds the *
to the name rather than to the type, or about how the left-aligned approach makes it marginally more awkward to get right that really important and frequently-used construct, the multi-variable declaration. Ignore them!
Speaking more broadly, you have a lot of pointers going on here, and I suggest trying to minimise that. It's only going to lead to unnecessary trouble. Love objects.
Upvotes: 1
Reputation: 87
The resolution to my issue is that I needed to return a void pointer. This may cause issues down the road with other things unrelated to this current problem, but this format had specific parameters to follow, which is why I mentioned main cannot change, among other things (including format). Thanks again.
Upvotes: 0
Reputation: 117288
void *Test::min(const Test *&p) { /* modifies vec */ }
If this function doesn't have a return statement, remove the *
from void *
.
Upvotes: 0