Constructor for derived class

I am adding some methods to the NTPClient by creating a derived class MyNTP.

But now, I can't figure out how to invoke the new class. That is, I can't figure out how to write the constructor for this.

NTPClient.h contains a bunch of constructors...
1
2
3
4
5
6
7
8
  NTPClient(UDP &udp);
  NTPClient(UDP &udp, long timeOffset);
  NTPClient(UDP &udp, const char *poolServerName);
  NTPClient(UDP &udp, const char *poolServerName, long timeOffset);
  NTPClient(UDP &udp, const char *poolServerName, long timeOffset, unsigned long updateInterval);
  NTPClient(UDP &udp, IPAddress poolServerIP);
  NTPClient(UDP &udp, IPAddress poolServerIP, long timeOffset);
  NTPClient(UDP &udp, IPAddress poolServerIP, long timeOffset, unsigned long updateInterval);


But lets just focus on the first, and simplist of these constructors.

In NTPClient.cpp it is defined as:
1
2
3
NTPClient::NTPClient(UDP& udp) {
  this->_udp            = &udp;
}


So, I create MyNPT.cpp with the following constructor:
1
2
3
4
5
6
7
8
#include "Arduino.h"
#include "NTPClient.h"
#include "MYNPT.h"

void MyNPT(UDP& udp)
        : NTPClient(udp)
    {
    }

and MyNPT.h as follows
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef _MY_NTP_H_
#define _MY_NTP_H_
#include "Arduino.h"

#include "NTPClient.h"
#include <Udp.h>

class MyNTP : public NTPClient
{
public:
  void MyNPT(UDP& udp); 
};

#endif //_MY_NTP_H_ 

and I get the following errors...
1: MyNPT.h " Function definition for 'MyNPT' not found. "
2: MyNPT.cpp At the ":" " expected a '{' "

This shouldn't be this hard.. What am I missing?
THANKS!
Your constructor needs to be:
1
2
3
4
5
6
7
#include "Arduino.h"
#include "NTPClient.h"
#include "MYNPT.h"

void MyNPT::MyNPT(UDP& udp)
        : NTPClient(udp)
    {

Line 5-8 in MyNPT.cpp should be:

1
2
3
4
MyNPT::MyNPT(UDP& udp)
:	NTPClient(udp)
{
}


If you want to "inherit" all the constructors from NTPClient you can just write:

1
2
3
4
5
class MyNTP : public NTPClient
{
public:
	using NTPClient::NTPClient;
};

See: https://en.cppreference.com/w/cpp/language/using_declaration#Inheriting_constructors
Last edited on
@AbstractionAnon thank you
@Peter87 Thank you for taking it one step further and providing the using method for inheriting all of the constructors and for the reference link.

Much appreciated!
Well... still stuck here... still getting error: 'MyNPT' does not name a type on line 6 of MyNPT.cpp below

MyNPT.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "Arduino.h"
#include "NTPClient.h"
#include "MyNPT.h"

MyNPT::MyNPT(UDP& udp)  //*** error: 'MyNPT' does not name a type
        : NTPClient(udp)
    {
    }
    
String MyNTP::getDayName() const
{
    const String thedays[] = {
        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    return (thedays[this->getDay()]);
}


MyNPT.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef _NTP_HELPERS_H_
#define _NTP_HELPERS_H_

#include "Arduino.h"
#include "NTPClient.h"
#include <Udp.h>

class MyNTP : public NTPClient
{
public:
    using NTPClient::NTPClient; // inherit all constructors
    
    String getDayName() const;
};

#endif // _NTP_HELPERS_H_ 
Last edited on
Looks like a name collision between header guards.

Check that _NTP_HELPERS_H_ is not defined by another file - especially if you still have NTPHelpers.h still sticking around.

It is worth noting that names that start with an underscore followed by a capital letter are reserved by the implementation. See [lex.name]/3:
http://eel.is/c++draft/lex.name#3.1
So try changing _NTP_HELPERS_H_ to MY_NTP_H_, fixing the name and dropping the leading underscore.
Last edited on
Look at the spelling.

You have NTP in some places, and NPT in other places.

That being said, I have never used this "inheriting constructors" feature. Seems like it could make things hard to reason with at a glance.

I tried making a minimum example based off your code, but I get a compiler error:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
struct UDP { };

class NTPClient
{
public:
    NTPClient(UDP& udp) { }
};


class MyNTP : public NTPClient
{
public:
    using NTPClient::NTPClient; // inherit all constructors
};

MyNTP::MyNTP(UDP& udp)
 : NTPClient(udp)
{
}

int main()
{
    UDP dup;
    MyNTP my_npt(dup);
}


main.cpp:16:8: error: out-of-line definition of 'MyNTP' does not match any declaration in 'MyNTP'
MyNTP::MyNTP(UDP& udp)
       ^~~~~
1 error generated.


It compiles if you remove lines 16-19, but I assume you are trying to do custom logic in the constructor?


I don't think you can inherit the constructors and also try to make your own.
It's all or nothing. You might just have to duplicate the boilerplate...
but maybe someone who knows more about this feature can say otherwise.
Last edited on
Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>

class mySt {
public:
	mySt(const std::string& s);
	mySt();
};

class myCl : public mySt {
	using mySt::mySt;

public:
	myCl(int a);
};

mySt::mySt() {
	std::cout << "def mySt\n";
}

mySt::mySt(const std::string& s) {
	std::cout << "mySt str const\n";
}

myCl::myCl(int a) {
	std::cout << "myCl int\n";
}

int main() {
	myCl s { "foobar" };
	myCl i { 1234 };
}

This compiles. Note line 12:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct UDP { };

class NTPClient {
public:
	NTPClient(UDP& udp) {}
};

class MyNTP : public NTPClient {
public:
	using NTPClient::NTPClient; // inherit all constructors

	MyNTP(UDP&);
};

MyNTP::MyNTP(UDP& udp)
	: NTPClient(udp) {}

int main() {
	UDP dup;
	MyNTP my_npt(dup);
}


But what you're probably after is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct UDP { };

class NTPClient {
public:
	NTPClient(UDP&) {}
};

class MyNTP : public NTPClient {
public:
	using NTPClient::NTPClient; // inherit all constructors
};

int main() {
	UDP dup;
	MyNTP my_npt(dup);
}

Last edited on
Yeah, the inheriting constructors are just for getting the constructors exactly as they are in the base class. If you want to define some of them yourself you still need to declare them in the constructor body. You could also choose to "delete" certain constructors that you don't want.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// in MyNTP.h
class MyNTP : public NTPClient
{
public:
	using NTPClient::NTPClient;
	
	MyNTP(UDP &udp); // I want to define this constructor myself
	MyNTP(UDP &udp, long timeOffset) = delete; // I don't want this constructor!
};


// in MyNTP.cpp
MyNTP::MyNTP(UDP& udp)
:	NTPClient(udp)
{
	// You can add extra logic here if you want...
}
Last edited on
"You have NTP in some places, and NPT in other places."

how embarrassing... Dyslexics of the world, UNTIE!
Thank you all!

@SeePlus, Yes, exactly, thank you!


But what you're probably after is:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct UDP { };

class NTPClient {
public:
	NTPClient(UDP&) {}
};

class MyNTP : public NTPClient {
public:
	using NTPClient::NTPClient; // inherit all constructors
};

int main() {
	UDP dup;
	MyNTP my_npt(dup);
}

Topic archived. No new replies allowed.