0

I'm having trouble inheriting/invoking the constructor of a base class. I based the class off of a Boost.Asio example.

Here's the parent class:

#ifndef CLIENT_HPP
#define CLIENT_HPP

#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>

using boost::asio::ip::tcp;

class client : public std::enable_shared_from_this<client> {

    public:
        client(tcp::socket socket) : socket_(std::move(socket)) {

        }

        void start() {
        }

        tcp::socket socket_;

};

#endif

Here is the child class:

#ifndef PENGUIN_HPP
#define PENGUIN_HPP

#include "Client.hpp"

class penguin : public client {

    public:
        penguin() : client(socket_) {

        }

};

#endif

This is how I'm initializing the Penguin class

std::make_shared<penguin>(std::move(socket_))->start();

socket_ here is the server's tcp::socket thingy.

I'm a C++ noob, so any help would be greatly appreciated!

Nyaa
  • 1
  • 2
  • 1
    It sounds like you are looking for a [delegating constructor](http://stackoverflow.com/questions/13961037/delegate-constructor-c) – Cory Kramer Oct 10 '14 at 16:03
  • 1
    Sounds like `penguin`'s constructor should take an argument. – T.C. Oct 10 '14 at 16:10
  • I added an argument to `penguin`'s constructor. I get this **error**: `error: use of deleted function ‘boost::asio::basic_stream_socket::basic_stream_socket(const boost::asio::basic_stream_socket&)’` – Nyaa Oct 10 '14 at 16:45
  • That error means what it says: the function you're trying to call doesn't exist. – derpface Oct 13 '14 at 17:31

2 Answers2

3

First, let's clarify. In C++, constructors are not inherited. The behavior of constructors in a class hierarchy might make it seem at times that constructors are inherited, and some would argue that I'm being overly pedantic, but I think it's important to understand this distinction.

Now the question is how do you invoke the constructor of a base class in your derived class' constructor. The answer is within the derived class' constructor initialization list -- just as you are doing.

However there is a problem with how you are actually going about it

penguin() : client(socket_) {}

Here, socket_ is a member of the base class, client (unless there's a typo in your post.). socket_ is being referenced before the client object has been instantiated, so it doesn't even exist yet. This is a chicken-egg problem of sorts. In order to instantiate client, you need socket_, but in order to reference socket_, you need to instantiate client, and the beat goes on...

I don't have a succinct piece of advice I can give you to fix this problem you're having, because unfortunately there's no easy fix. The real problem here is that your design is broken. It's broken because of the cyclic dependency you're introduced between the base class and the members of that base class. You need to revisit your design.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
0

What you're attempting to do can be simplified in this example:

class foo
{
public:
    foo(int x);

protected:
    int m_x;
};

class bar : public foo
{
public:
    bar();
};

// in bar.cpp:
bar::bar()
    :foo(foo::x)
{
}

Obviously it makes no sense. You can't initialize an object with its own data member that doesn't exist yet. In your case, you're trying to initialize a client with its own socket_. You need to construct a socket somewhere else first. When you declare an instance of a class, it gets constructed in order from its most-base type to its most-derived type (client constructor completes first, then penguin, etc), and it gets destructed in reverse order. The penguin constructor doesn't "override" the client constructor.

You're also initializing your penguin instance as if it takes a socket parameter in its constructor, when it does not. If you want your penguin to take in a socket to be used by its parent's constructor, then add a socket parameter to penguin's constructor. In any case, you still need to construct a socket separately and pass it in to the constructor.

I'm also curious what your definition of C++ noob is, and why you're attempting network programming with boost::asio and move semantics if you don't even know the basics of classes and constructors yet. Maybe you should start smaller.

derpface
  • 1,611
  • 1
  • 10
  • 20