Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
What is the syntax for dynamically allocating an object with an overloaded constructor in C++?
If I have a class Foo:
class Foo{
public:
Foo(string str, int nbr); // Overloaded constructor
};
And a second class Foo2 (using Foo):
#include "Foo"
class Foo2{
public:
Foo* myFoo; // Wrong!
Foo2(){
myFoo = new Foo(myStr, myNbr);
}
};
The error displayed is the following :
no matching function for call to "Foo::Foo()"
How can I, when creating myFoo object pointer, specify that it will use the Foo(string str, int nbr) constructor, not Foo() constructor.
Is it possible without using constructor delegation?
Your syntax to construct the object is correct.
It's hard to say for sure since you haven't told the error, but my guess is that your problem is that the constructor is private. That means you cannot use the constructor outside the class.
Edit concerning the error message:
Here's a complete example that compiles. I've added some example lines that would produce the error: no matching function for call to 'Foo::Foo()'.
#include <string>
class Foo{
public:
Foo(std::string str, int nbr);
};
// empty definition
Foo::Foo(std::string str, int nbr) {}
// delegating constructor (c++11 feature)
// this would produce error: no matching function for call to 'Foo::Foo()'
//Foo::Foo(std::string str, int nbr) : Foo::Foo() {}
int main() {
Foo* myFoo;
myFoo = new Foo("testString", -1); // this is correct
// trying to construct with default constructor
//Foo myFoo2; // this would produce error: no matching function for call to 'Foo::Foo()'
//Foo* myFoo3 = new Foo(); // so would this
}
Given the error, your code is trying to use the default constructor somewhere.
Edit2 concerning your new Foo2 example. Your declaration of Foo* and the call to the constructor are still correct and the code should compile if you fix the method visibility and missing semicolons. Following example compiles:
#include <string>
class Foo{
public:
Foo(std::string str, int nbr); // Overloaded constructor
};
Foo::Foo(std::string str, int nbr){}
class Foo2{
Foo* myFoo; // This is still correct
public:
Foo2() {
myFoo = new Foo("", 1);
}
};
int main() {
Foo2 foo2;
}
Syntax is correct.
There are many possibilities as you have not written full class definition.
1. check whether default cnstsructor is written.
2. Check whether both constructors are inside public section.
3. Alternatively you can change call to constructor as below,
Foo* myFoo = new Foo("testString", -1);
The following code should work.
class Foo
{
string str;
int num;
public:
Foo(string p_str, int nbr):str(p_str),num(nbr){}; // Overloaded constructor
Foo() {}; // Default constructor
};
The correct way is initializing the members in each constructor. You could extract their common code in a private init() member function and call it in each constructor like the following:
class Foo {
public:
Foo(string x);
Foo(string x, int y);
...
private:
void init(string x, int y);
};
Foo::Foo(string x)
{
init(x, int(x) + 3);
...
}
Foo::Foo(string x, int y)
{
init(x, y);
...
}
void Foo::init(string x, int y)
{
...
}
Related
Lets say I have the follow code
template<class MemberFunc>
class Foo {
MyClass object_;
void call() {
auto ptr = MemberFunc{};
(object_.*ptr)();
}
};
int main() {
Foo<decltype(&MyClass::doThings)> foo;
foo.call();
}
This code does crash for me because ptr is 0. Why does the member function constructor returns 0?
My workaround is the following but it involves code duplication. Is there no other way to just construct/instantiate the member function from the type? C++14 welcome.
template<class MemberFunc, MemberFunc f>
class Foo {
MyClass object_;
void call() {
(object_.*f)();
}
};
int main() {
Foo<decltype(&MyClass::doThings), &MyClass::doThings> foo;
foo.call();
}
Why does the member function constructor returns 0?
Because it's a pointer (-to-member-function), and all scalar types value-initialize to 0 (C++14 [dcl.init]/8.4).
Is there no other way to just construct/instantiate the member function from the type?
You can have multiple member functions with the same signature; how would it know which member function you want to refer to?
The code you have is fine for C++14. In C++17, it can be shortened to the following:
template<auto f>
class Foo {
MyClass object_;
void call() {
(object_.*f)();
}
};
int main() {
Foo<&MyClass::doThings> foo;
foo.call();
}
You can't instantiate a member function from its type. For example, consider the following class:
struct foo
{
void bar(int){}
void baz(int){}
};
Suppose you have a type void (foo::*)(int). Which function would you like to get from it?
As of C++1z, you'll be able to use auto to deduce non-type, non-template template parameters:
template<auto f>
class Foo {
MyClass object_;
void call() {
(object_.*f)();
}
};
int main() {
Foo<&MyClass::doThings> foo;
foo.call();
}
demo
The only workaround for C++11/14 I can think of is using a macro:
#define type_value_pair(x) decltype(x), x
template<class MemberFunc, MemberFunc f>
class Foo {
MyClass object_;
void call() {
(object_.*f)();
}
};
int main() {
Foo<type_value_pair(&MyClass::doThings)> foo;
foo.call();
}
demo
But I'd advise against using this, for readability reasons.
decltype returns the type of its argument. Using the following example:
class MyClass {
public:
int foo();
int bar();
};
Both
decltype(&MyClass::foo);
and
decltype(&MyClass::bar);
is the same type: int (MyClass::*)().
When you default-initialize this type, the default initialization results in a nullptr. Hence the crash.
When you value-initialize a pointer to member-function, you will receive a nullptr, of course.
By the way, you can have multiple member function with the same type as you can see in Sam's answer.
I don't know why do you need to put the MemberFunc to template parameter list of Foo.
However, if you want to make a function to call it, this maybe a better approach in C++ before C++1z (use auto in C++1z is better match for this question):
class Foo {
MyClass object_;
public:
template<class MemberFunc>
void call(MemberFunc ptr) {
(object_.*ptr)();
}
};
int main() {
Foo foo;
foo.call(&MyClass::doThings);
}
In the header file of class Class1, I've declared a function pointer fn_ptr and a function called myfunc(int,int):
class Class1
{
private:
bool (*fn_ptr)(int,int);
public:
Class1(); //Default Constructor
bool myfunc(int,int);
};
I want to have fn_ptr point to Class1's myfunction defined like so in the class's library file:
Class1::Class1()
{
fn_ptr = myfunc; //Initialization in the
}
Class1::myfunc(int a, int b)
{
return a<b;
}
Compiling resulted in an error:
error: argument of type 'bool (Class1::)(int,int)' does not match 'bool (*)(int,int)'
As user4581301 wrote in the comment, once you have a (non-static) member function, it takes a "hidden" pointer to the class's object, so you can't do directly what you tried here - the interfaces just don't match.
Also, there are currently more convenient facilities for function indirection that bare pointers.
Suppose you do the following. First, declare the class like this:
#include <functional>
using namespace std;
class Class1
{
private:
std::function<bool(int, int)> fn;
public:
Class1(); //Default Constructor
bool myfunc(int,int){ return true; }
};
Note how the member fn is of type std::function, which is more convenient and versatile.
Now in the constructor, you can simply initialize it with a lambda function:
Class1::Class1() :
fn([this](int i, int j){return myfunc(i, j);})
{
}
It says that for any i and j, just call myfunc (on this objet) on these arguments, and return the result.
Full code
Make sure to build using c++11 settings.
#include <functional>
using namespace std;
class Class1
{
private:
std::function<bool(int, int)> fn;
public:
Class1(); //Default Constructor
bool myfunc(int,int){ return true; }
};
Class1::Class1() :
fn([this](int i, int j){return myfunc(i, j);})
{
}
int main()
{
Class1 c;
}
In addition to #Ami's excellent answer about using std::function instead, member function pointers have different syntax, which is why it didn't work for you.
bool (Class1::*fn_ptr)(int,int); //note the Class1::
fn_ptr = &Class1::my_func; //the &Class1:: is necessary, forgetting it is a compilation error
Calling it is different, too. It needs an instance of the class to be called on.
Class1 c;
(c.*fn_ptr)(1, 2); //or (this->*fn_ptr) too
I'm trying to learn to c++ after programming in other OO languages for many years.
I'm trying to create a wrapper class for another class, but having a hard time figuring out how to set this up properly.
For instance, with the following...
main.cpp
#include "foo.cpp"
#include <iostream>
int main() {
Foo foo(42);
std::cout << foo.get_barx() << std::endl;
return 0;
}
foo.cpp
#include "bar.cpp"
class Foo {
public:
// I'm trying to declare the member variable `m_bar` here. I
// don't want to be instantiating an instance of Bar yet,
// but I think that might be exactly what's happening.
Bar m_bar;
Foo(int y) {
// Here's where I really want to instantiate an instance of Bar
// and assign it to m_bar.
Bar m_bar(y*2);
}
int get_barx() {
return m_bar.getx();
}
};
bar.cpp
class Bar {
public:
int m_x;
// I seem to need this default constructor for the declaration
// of `m_bar` above, but I don't think that line should be
// calling any constructors.
Bar() { m_x = 21; };
Bar(int x) {
m_x = x;
}
int getx() {
return m_x;
}
};
When I compile and run this, I get back 21, but I expect 84. I'm pretty sure I'm doing something fundamentally wrong, and I'm pretty sure it's got something to do with how I'm declaring the m_bar member variable in Foo, but I can't figure out what the right way is to accomplish this.
main.cpp
#include "foo.cpp"
#include <iostream>
int main()
{
Foo foo(42);
std::cout << foo.get_barx() << std::endl;
return 0;
}
Here you should be including a header (e.g., rename "foo.cpp" to "foo.h"). In general, the header provides the declaration and the source (e.g., .cpp file) provides the definition/implementation.
Bar.cpp (again this should be a header)
class Bar
{
public:
int m_x;
// A default constructor is not required, however defining any constructor
// prevents auto generation of the default constructor
Bar(int x) : // This starts the initializer list section
m_x(x)
{
// This is assignment not initialization
// m_x = x;
}
// See the trailing 'const', research const correctness
int getx() const
{
return m_x;
}
};
foo.cpp (again this should be a header)
#include "bar.cpp"
class Foo
{
public:
// Just declaring a `Bar` data member
Bar m_bar;
Foo(int y) :
m_bar(y) // Initialize `Bar` data member using the available constructor
{
// First, this declares a new `Bar` instance which is different than
// the class member, regardless of the fact they are named the same
// Bar m_bar(y*2);
// Furthermore, even if you did the following it is assignment not initialization
// m_bar = Bar(y*2);
// Since initialization already occurred before this point an error
// will result if the `Bar` data member isn't instantiated via the
// only available constructor, since there isn't a default constructor as
// explained above
}
// Same comment about const correctness
int get_barx() const
{
return m_bar.getx();
}
};
You need to use initialization lists to construct class members at construction time. The body of the constructor gets called after all members have been constructed. If you don't explicitly call a non-default constructor then the compiler will insert a call to the default constructor for you. For example, your Foo class could look like:
class Foo {
public:
Foo(int y) : m_bar(y*2) {}
...
private:
Bar m_bar;
}
I have a forward declaration but want to have a instatance of the forward declarated class as default value.
So my code looks more or less like this:
bar.h
class Foo;
class Bar
{
public:
Bar();
void test(Foo foo = Foo(7));
}
and foo.h
class Foo
{
public:
Foo(int val);
}
Is this even possible?
No. When you declare a method/function which argument is Foo the compiler should already know the size of Foo, so it should be already defined at that moment. If you declared but not defined Foo you may use only pointers or references to it.
It's impossible as described in another answer.
Apart of that, default values are the code smell. They make your interfaces fragile
Use method overloading instead:
class Foo;
class Bar
{
public:
Bar();
void test(); // implement with default value, and document it
void test(Foo foo); // implement with user-supplied value
}
In bar.cpp:
#include "foo.h" // Complete Foo is available here
void Bar::test()
{
test(Foo(42));
}
void Bar::test(Foo foo)
{
...
}
Alright, I just thought give C++ a try (I currently do C#), now my first problem is class instantiating or calling a method in another class.
Here is my code:
My main Program entry:
#include <iostream>
#include "myClass.h"
using namespace std;
int main()
{
myClass* mc = new myClass();
}
The Class I'm trying to access:
#include "myClass.h"
myClass::myClass()
{
void DoSomething();
{
}
}
myClass::~myClass()
{
}
The Class Header:
#pragma once
class myClass
{
public:
myClass();
~myClass();
};
Now as you can see i have instantiated the class, but i cant access DoSomething() method.
This code simply declares a local function, and has an empty scope for fun:
myClass::myClass()
{
void DoSomething(); // local function declaration
{
// empty scope
}
}
If you want doSomething() to be a member of myclass, you have to declare it in the class definition:
class myClass
{
public:
myClass();
~myClass();
void doSomething();
};
then implement it
void myclass::doSomething() { .... }
Also note that you don't have to use new everywhere in C++. You can instantiate an object like this:
int main()
{
myClass mc;
}
Also note that using namespace std; isn't such a great idea anyway, at least not in real code.
this is a function declaration in a constructor (+an ampty scope within { }).
myClass::myClass()
{
void DoSomething();
{
}
}
You want a function declaration in class body (not in constructor) and definition of this function (this can be done immediately together with declaration or later as i.e. here):
class myClass
{
public:
myClass();
~myClass();
void doSomething();
};
implementation of constructor:
myClass::myClass() { .... }
implementation of your function, similarly:
void myClass::doSomething() { .... }
The method you are trying to use in main must be part of the class definition. You can write an inline function or can have a separate definition of that function. Also, you need to make that function public in order to access it from main.