can't call member function of a class-object returned by a function

Getting the following compile-error:
g++ -c -Wall -pthread -I/usr/include/gnet-2.0 -I/usr/lib/gnet-2.0/include/ -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include  -pthread -lgnet-2.0 -lgthread-2.0 -lrt -lglib-2.0 main.cpp -o main.o
main.cpp: In function »int main()«:
main.cpp:9: Fehler: »gruetze.UDPServer::getClientManager« hat keinen Klassentyp
make: *** [main.o] Fehler 1
//ClientManager Class
class ClientManager{
private:
vector<Client> clients;
 
public:
  ClientManager(void);
  bool registerClient(Client test);
  int getCount(void);
  ~ClientManager(void);
};
 
//Class udpserver
class UDPServer{
 
private:
  int lport;
  GUdpSocket* server;
  gint ttl;
  gint rv;
  GInetAddr* addr;
  gchar buffer[1024];
  pthread_t serverthread;
  ClientManager cm;
  void* thread();
  static void* _run(void* This)
  {
    return ((UDPServer*)This)->thread();
  };
 
public:
  UDPServer(int port);
  ClientManager getClientManager();
  ~UDPServer();
};
 
//function-code:
ClientManager UDPServer::getClientManager()
{
return this->cm;
}
 
//Called function:
int ClientManager::getCount(void)
{
return clients.size();
}
 
 
//Line containing the error:
printf("%s",gruetze.getClientManager.getCount());

Open in new window

LVL 2
ktd85Asked:
Who is Participating?
 
Infinity08Connect With a Mentor Commented:
We're going a bit off topic here, as this is no longer related to your original question. If your original question has been answered, you should close this question. If you have further questions, you can create new question(s) for them.

>> is there any way to manage to vector without temporary objects?

pass by reference will help. Storing pointers in the vector rather than objects, might help too ...
0
 
Infinity08Commented:
Could you post the complete code ? At least the part where the error occurs (line 9 in main.cpp, as well as the declarations for all variables used, etc.).
0
 
ktd85Author Commented:

//main.cpp
#include "udpserver.h"
#include "serial.h"
 
int main()
{
UDPServer gruetze(1337);
while (true)
{
gruetze.getClientManager();
sleep(100);
}
}
 
//udpserver.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <unistd.h>
#include <string>
#include "clientmanager.h"
#include <gnet.h>
#include <udp.h>
#include <pthread.h>
 
class UDPServer{
 
private:
  int lport;
  GUdpSocket* server;
  gint ttl;
  gint rv;
  GInetAddr* addr;
  gchar buffer[1024];
  pthread_t serverthread;
  ClientManager cm;
  void* thread();
  static void* _run(void* This)
  {
    return ((UDPServer*)This)->thread();
  };
 
public:
  UDPServer(int port);
  ClientManager getClientManager();
  ~UDPServer();
};
 
 
//udpserver.c
#include "udpserver.h"
using namespace std;
 
 
 
UDPServer::UDPServer(int port)
{
  this->lport=port;
  gnet_init ();
  this->server=gnet_udp_socket_new_with_port(port);
  if (this->server == NULL)
    {
      fprintf (stderr, "Could not create server on port %d\n", port);
      exit (EXIT_FAILURE);
    }
  pthread_create( &serverthread, NULL, _run, this);
}
 
ClientManager UDPServer::getClientManager()
{
cm.getCount();
return NULL;
//return this->cm;
}
 
void* UDPServer::thread()
{
while (true)
  {
     gint bytes_received;
     std::string b;
     bytes_received = gnet_udp_socket_receive (this->server, this->buffer, sizeof(this->buffer),&this->addr);
     b=this->buffer;
     b.erase(bytes_received);
     if (b.find("ch bin da"))
     {
       Client m;
       cm.registerClient(m);
     }
     printf("%s",b.c_str());
  }
}
 
UDPServer::~UDPServer() {
  pthread_join( serverthread, NULL );
}

Open in new window

0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
Infinity08Commented:
I assume that gruetze is an object of type UDPServer ?

Then, if you want to call the getClientManager method on it, you need to do :

        gruetze.getClientManager()

instead of :

>>    gruetze.getClientManager

Note that the getClientManager method returns a copy of the ClientManager object ... Maybe it should be returned by reference, or by pointer ?

Furthermore, you continue by calling the getCount method on the ClientManager object, but that method returns an int, not the char* that your printf expects (%s).
0
 
Infinity08Commented:
btw, the code you posted is not the same code you posted earlier - it doesn't contain the printf ...
0
 
ktd85Author Commented:
oh, sorry. i modified...
0
 
Infinity08Commented:
So, does that solve your problem ? If not, can you post the new code, as well as the new error message you get ?
0
 
ktd85Author Commented:
Corrected the ()-thing.
Is there a method to return the referenc to the original object?
Do have to change the function-call?
0
 
ktd85Author Commented:
addition to my last post. After i corrected the ()-thing the code worked!
Is there a method to return the referenc to the original object?
Do have to change the function-call?
0
 
Infinity08Commented:
>> addition to my last post. After i corrected the ()-thing the code worked!

Did you also fix the int vs. %s thing ? By using %d instead of %s for example.


>> Is there a method to return the referenc to the original object?
>> Do have to change the function-call?

It depends what you're trying to do. But you could return a reference to the object instead of a copy to the object, yes. That would indeed involve modifying the method.
Type obj;
 
Type fun_copy() {           // <--- return a copy of the object
  return obj;
}
 
Type &fun_ref() {           // <--- return a reference to the object
  return obj;
}
 
 
// and the calling code :
 
Type obj2 = fun_copy();
obj2.some_method();         // <--- will be called on the copy, not the original object
 
Type &obj_ref = fun_ref();
obj_ref.some_method();      // <--- will be called on the original object (obj)

Open in new window

0
 
ktd85Author Commented:
Yes, i corrected the %d-thing too.

Is there a possibility to make the call in one line?
Type &obj_ref = fun_ref();
obj_ref.some_method();  
0
 
Infinity08Commented:
>> Is there a possibility to make the call in one line?

Sure :

        fun_ref().some_method();

will call the some_method method on the original object (obj).
0
 
ktd85Author Commented:
I included a message in the constructor and destructor.
After starting the program i'm now receiving masses of the following message:
Client destroyed.
Client destroyed.
Client destroyed.
Client destroyed.
Client destroyed.

Is the refereced object destroyed after the method call?
//client.cpp
#include "client.h"
using namespace std;
 
Client::Client(void)
{
  fprintf (stdout, "Client created.\r\n");
}
 
Client::~Client(void) {
 fprintf (stdout, "Client destroyed.\r\n");
}
 
//changed method:
ClientManager &UDPServer::getClientManager()
{
return this->cm;
}
 
//main.cpp:
int main()
{
UDPServer gruetze(1337);
while (true)
{
printf("Anzahl der Clients: %d /r/n",gruetze.getClientManager().getCount());
sleep(2);
}
}

Open in new window

0
 
Infinity08Commented:
>> Client destroyed.

You'll receive one such message each time a Client object is destroyed.

The UDPServer::thread() code you posted earlier has an infinite loop that potentially creates and destroys a Client object for each iteration. That's probably the reason ...
0
 
ktd85Author Commented:
Hi,

i think the thread which is started in the udpserver-class does not cause this thing.
I commented out the following line of my main-loop and it stopped producing the messages:
printf("Anzahl der Clients: %d /r/n",gruetze.getClientManager().getCount());

any idea?
0
 
Infinity08Commented:
Nothing in the code you posted earlier suggests the creation of Client objects, except for the ones in the thread method.

Maybe you could post the complete, current code ?
0
 
ktd85Author Commented:
yes
//main.cpp
#include "udpserver.h"
#include "serial.h"
 
int main()
{
UDPServer gruetze(1337);
while (true)
{
//printf("Anzahl der Clients: %d /r/n",gruetze.getClientManager().getCount());
sleep(2);
}
}
 
 
//client.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
class Client{
public:
  Client(void);
  ~Client(void);
};
 
 
//client.cpp
#include "client.h"
using namespace std;
Client::Client(void)
{
  fprintf (stdout, "Client created.\r\n");
}
Client::~Client(void) {
 fprintf (stdout, "Client destroyed.\r\n");
}
 
//clientmanager.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <vector>
#include "client.h"
using namespace std;
class ClientManager{
private:
vector<Client> clients;
public:
  ClientManager(void);
  bool registerClient(Client test);
  int getCount(void);
  ~ClientManager(void);
};
 
//clientmanager.cpp
#include "clientmanager.h"
using namespace std;
ClientManager::ClientManager(void)
{
  fprintf (stdout, "Client Manager Class created.");
}
bool ClientManager::registerClient(Client test)
{
clients.push_back(test);
return true;
}
int ClientManager::getCount(void)
{
return clients.size();
}
ClientManager::~ClientManager(void) {
 fprintf (stdout, "Client Manager Class destroyed.");
}
 
//udpserver.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <unistd.h>
#include <string>
#include "clientmanager.h"
#include <gnet.h>
#include <udp.h>
#include <pthread.h>
 
class UDPServer{
 
private:
  int lport;
  GUdpSocket* server;
  gint ttl;
  gint rv;
  GInetAddr* addr;
  gchar buffer[1024];
  pthread_t serverthread;
  ClientManager cm;
  void* thread();
  static void* _run(void* This)
  {
    return ((UDPServer*)This)->thread();
  };
 
public:
  UDPServer(int port);
  ClientManager &getClientManager();
  ~UDPServer();
};
 
 
//udpserver.cpp
#include "udpserver.h"
using namespace std;
UDPServer::UDPServer(int port)
{
  this->lport=port;
  gnet_init ();
  this->server=gnet_udp_socket_new_with_port(port);
  if (this->server == NULL)
    {
      fprintf (stderr, "Could not create server on port %d\n", port);
      exit (EXIT_FAILURE);
    }
  pthread_create( &serverthread, NULL, _run, this);
}
ClientManager &UDPServer::getClientManager()
{
return this->cm;
}
void* UDPServer::thread()
{
while (true)
  {
     gint bytes_received;
     std::string b;
     if (!gnet_udp_socket_has_packet(this->server))
    {
    sleep(1);
    continue;
    }
     bytes_received = gnet_udp_socket_receive (this->server, this->buffer, sizeof(this->buffer),&this->addr);
     b=this->buffer;
     b.erase(bytes_received);
     if (b.find("ch bin da"))
     {
       Client m;
       cm.registerClient(m);
     }
     printf("%s",b.c_str());
  }
}
UDPServer::~UDPServer() {
  pthread_join( serverthread, NULL );
}

Open in new window

0
 
Infinity08Commented:
Again, the only location where Client objects are created, is here :

>>        Client m;
>>        cm.registerClient(m);

Note that registerClient makes two copies of the object passed to it - one temporary copy, and one copy that is saved in the vector.
So, the local m object, and the temporary copy will be destroyed as soon as their context ends, and then the Client objects in the vector are destroyed as soon as the ClientManager object is destroyed.

So ... you should probably make sure that all those temporary objects are not created, and you should probably manage that vector a bit better.
0
 
ktd85Author Commented:
Hi,

is there any way to manage to vector without temporary objects?

thx
thomas
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.