Rebecka
Rebecka

Reputation: 107

Function 'not declared in this scope', but it is! Isn't it?

'initPhysics' was not declared in this scope.

I have simplified my program as much as I could; here it is:

helloworld.hpp

#ifndef HELLOWORLD_HPP
#define HELLOWORLD_HPP

class testWorld {
    public:
        testWorld() {}
        ~testWorld() {}
        void initPhysics();
};
#endif

hello.cpp

#include "helloworld.hpp"
#include <iostream>

using namespace std;

void testWorld::initPhysics() {
    cout << "Initiating physics..." << endl;
}

int main(int argc,char** argv) {
    cout << "Hello World!" << endl;
    testWorld* world;
    world = new testWorld();
    world<-initPhysics();
    return 0;
}

I compile with the command

g++ -c hello.cpp

and get the error

hello.cpp: In function ‘int main(int, char**)’:
hello.cpp:14:21: error: ‘initPhysics’ was not declared in this scope

Why doesn't the compiler see the declaration of initPhysics, even though I included helloworld.hpp?

Upvotes: 2

Views: 3506

Answers (6)

sbi
sbi

Reputation: 224119

Learn to read the -> operator (not <-!) in ptr->member as "member in whatever ptr points to", in other words: it is a somewhat literal representation of an actual pointer. So in your case it should be

world->initPhysics(); // note the ->, not <-

However, while this answers your question, it's far from sufficient. There's several other problems with your code.

  1. There's no need to first create an uninitialized pointer, and then initialize it. That's error-prone, and you should instead initialize it immediately:

    testWorld* world = new testWorld();
    world->initPhysics();
    
  2. Note that in C++ every object created using the new operator needs to be destroyed explicitly using the delete operator:

    delete  world; // sounds scary, BTW
    
  3. You seem to be coming from a language like Java or C#, where everything must be new'd. In C++ this is not true. By default you should create objects on the stack, rather than on the heap:

    testWorld world;
    world.initPhysics();
    
  4. But there's still a problem with your code. What you have now is what's known as two-phase construction. As a user of your class I need to remember to call an initialization function before I use an instance of it. But that's what constructors are for! A constructor should fully initialize an object, so that it is in a usable state. You should call your initialization function from the constructor instead:

    testWorld() {initPhysics();}
    

Physics is an integral part of the world, and shouldn't be added as an afterthought. :)

Upvotes: 3

phoxis
phoxis

Reputation: 61940

world<-initPhysics(); should be world->initPhysics();

Upvotes: 0

Sven
Sven

Reputation: 22693

It should be world->initPhysics(), not world<-initPhysics()

Your version is being read as the expression "world is less than -1 multiplied by the result of the global function initPhysics()" and it's that global function that it can't find.

And although this is obviously test code, I'd just like to point out that if you allocate an object with new, you must explicitly delete it somewhere.

Upvotes: 15

deadalnix
deadalnix

Reputation: 2325

world<-initPhysics();

Here, your arrow is in the wrong direction. You should have :

world->initPhysics();

Upvotes: 0

pmr
pmr

Reputation: 59831

You want world->initPhysics(); instead of world<-initPhysics();

Upvotes: 0

Jeff Foster
Jeff Foster

Reputation: 44706

world<-initPhysics() should be world->initPhysics()?

Upvotes: 3

Related Questions