N. Colostate
N. Colostate

Reputation: 87

Modifying a pointer within a function (passing another pointer as a parameter)

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

Answers (3)

Lightness Races in Orbit
Lightness Races in Orbit

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

N. Colostate
N. Colostate

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

Ted Lyngmo
Ted Lyngmo

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

Related Questions