In my code, I want to create a dynamic array of objects. I don't know how many objects I want until the runtime, and the array's class has a dynamic variable array, so my objects can be of any size. Therefore, to make an array of them, I want to create an array of pointers as pointers are of a fixed size. Then, during runtime, when I know how many objects I will store, I want to malloc the memory needed to store the pointers. When I try mallocing, I get a linking error unless I define the array at the top of the .cpp file, even though it's already declared in the header .h file, and I am not sure why this is necessary.
My code:
Maintest.cpp
#include <iostream>
#include "class.h"
#include "Maintest.h"
//Class** Maintest::testArray = NULL; //uncommenting this line fixes the linking error
void Maintest::createMany(){
testArray = (Class **) malloc(10 * sizeof(Class *));
}
int main(){
printf("hello");
}
Maintest.h
class Maintest {
private:
static Class** testArray;
public:
static void createMany();
};
class.cpp
#include <iostream>
#include "class.h"
Class::Class(int arg){
test = arg;
}
class.h
class Class {
private:
int test;
public:
Class::Class(int);
};
In olden times, it wasn't enough to declare a static variable in your class; you had to define it in exactly one source file. This is why uncommenting that line fixes your linker error.
But since C++17, you can get round this by declaring the variable as static inline in the class definition:
class Maintest {
private:
static inline Class** testArray;
public:
static void createMany();
};
Related
I would like to split a class implementation into three parts, to avoid that users need to deal with the implementation details, e.g., the libaries that I use to implement the functionality:
impl.cpp
#include <api.h>
#include <impl.h>
Class::Class() {
init();
}
Class::init() {
myData = SomeLibrary::Type(42);
}
Class::doSomething() {
myData.doSomething();
}
impl.h
#include <somelibrary.h>
class Class {
public:
Class();
init();
doSomething();
private:
SomeLibary::Type myData;
}
api.h
class Class {
Class();
doSomething();
}
The problem is, that I am not allowed to redefine headers for the class definition. This does not work when I define Class() and doSomething() only in api.h, either.
A possible option is to define api.h and do not use it in the project at all, but install it (and do not install impl.h).
The obvious drawback is, that I need to make sure, that the common methods in api.h and impl.h always have the same signature, otherwise programs using the library will get linker errors, that I cannot predict when compiling the library.
But would this approach work at all, or will I get other problems (e.g. wrong pointers to class members or similar issues), because the obj file does not match the header?
The short answer is "No!"
The reason: any/all 'client' projects that need to use your Class class have to have the full declaration of that class, in order that the compiler can properly determine such things as offsets for member variables.
The use of private members is fine - client programs won't be able to change them - as is your current implementation, where only the briefest outlines of member functions are provided in the header, with all actual definitions in your (private) source file.
A possible way around this is to declare a pointer to a nested class in Class, where this nested class is simply declared in the shared header: class NestedClass and then you can do what you like with that nested class pointer in your implementation. You would generally make the nested class pointer a private member; also, as its definition is not given in the shared header, any attempt by a 'client' project to access that class (other than as a pointer) will be a compiler error.
Here's a possible code breakdown (maybe not error-free, yet, as it's a quick type-up):
// impl.h
struct MyInternal; // An 'opaque' structure - the definition is For Your Eyes Only
class Class {
public:
Class();
init();
doSomething();
private:
MyInternal* hidden; // CLient never needs to access this! Compiler error if attempted.
}
// impl.cpp
#include <api.h>
#include <impl.h>
struct MyInternal {
SomeLibrary::Type myData;
};
Class::Class() {
init();
}
Class::init() {
hidden = new MyInternal; // MUCH BETTER TO USE unique_ptr, or some other STL.
hidden->myData = SomeLibrary::Type(42);
}
Class::doSomething() {
hidden->myData.doSomething();
}
NOTE: As I hinted in a code comment, it would be better code to use std::unique_ptr<MyInternal> hidden. However, this would require you to give explicit definitions in your Class for the destructor, assignment operator and others (move operator? copy constructor?), as these will need access to the full definition of the MyInternal struct.
The private implementation (PIMPL) idiom can help you out here. It will probably result in 2 header and 2 source files instead of 2 and 1. Have a silly example I haven't actually tried to compile:
api.h
#pragma once
#include <memory>
struct foo_impl;
struct foo {
int do_something(int argument);
private:
std::unique_ptr<foo_impl> impl;
}
api.c
#include "api.h"
#include "impl.h"
int foo::do_something(int a) { return impl->do_something(); }
impl.h
#pragma once
#include <iostream>
struct foo_impl {
foo_impl();
~foo_impl();
int do_something(int);
int initialize_b();
private:
int b;
};
impl.c
#include <iostream>
foo_impl::foo_impl() : b(initialize_b()} { }
foo_impl::~foo_impl() = default;
int foo_impl::do_something(int a) { return a+b++; }
int foo_impl::initialize_b() { ... }
foo_impl can have whatever methods it needs, as foo's header (the API) is all the user will see. All the compiler needs to compile foo is the knowledge that there is a pointer as a data member so it can size foo correctly.
Is there a way to avoid the Graph:: repetition in the implementation file, yet still split the class into header + implementation? Such as in:
Header File:
#ifndef Graph_H
#define Graph_H
class Graph {
public:
Graph(int n);
void printGraph();
void addEdge();
void removeEdge();
};
#endif
Implementation File:
Graph::Graph(int n){}
void Graph::printGraph(){}
void Graph::addEdge(){}
void Graph::removeEdge(){}
I'm guessing this is to avoid lots of "unnecessary typing". Sadly there's no way to get rid of the scope (as many other answers have told you) however what I do personally is get the class defined with all my function prototypes in nice rows, then copy/paste into the implementation file then ctrl-c your ClassName:: on the clip board and run up the line with ctrl-v.
If you want to avoid typing the "Graph::" in front of the printGraph, addEdge etc., then the answer is "no", unfortunately. The "partial class" feature similar to C# is not accessible in C++ and the name of any class (like "Graph") is not a namespace, it's a scope.
No there's not. Not directly at least. You could go for preprocessor tricks, but don't do it.
#define IMPL Graph::
IMPL Graph(int n){}
void IMPL printGraph(){}
void IMPL addEdge(){}
void IMPL removeEdge(){}
Also, you shouldn't even want to do it. What's the point. Besides it being a C++ rule, it lets you know you're actually implementing a member function.
One option is using. If you have method definitions which are in a cpp file that never gets #included, then using is safe (doesn't affect other files):
foo.h:
class FooLongNameSpecialisationsParamaters
{
int x_;
public:
int Get () const;
void Set (int);
};
foo.cpp:
#include "foo.h"
using Foo = FooLongNameSpecialisationsParamaters;
int Foo::Get () const
{
return x_;
}
void Foo::Set (int x)
{
x_ = x;
}
main.cpp:
#include "foo.h"
int main ()
{
//Foo foo; <-- error
FooLongNameSpecialisationsParamaters foo;
return 0;
}
No, there is no way to avoid it. Otherwise, how would you know if a given function definition is for a class function or for a static function?
If you are asking if you can define a member function such as Graph::printGraph without specifying the class name qualification, then the answer is no, not the way that you want. This is not possible in C++:
implementation file:
void printEdge(){};
The above will compile just fine, but it won't do what you want. It won't define the member function by the same name within the Graph class. Rather, it will declare and define a new free function called printEdge.
This is good and proper, if by your point of view a bit of a pain, because you just might want two functions with the same name but in different scopes. Consider:
// Header File
class A
{
void foo();
};
class B
{
void foo();
};
void foo();
// Implementation File
void foo()
{
}
Which scope should the definition apply to? C++ does not restrict you from having different functions with the same names in different scopes, so you have to tell the compiler what function you're defining.
//yes it is possible using preprocessor like this:
#define $ ClassName //in .cpp
void $::Method1()
{
}
//or like this: in the header .h:
#undef $
#define $ ClassName'
// but you have to include the class header in last #include in your .cpp:
#include "truc.h"
#include "bidule.h" ...
#include "classname.h"
void $::Method() { }
//i was using also
#define $$ BaseClass
//with single inheritance than i can do this:
void $::Method()
{
$$::Method(); //call base class method
}
//but with a typedef defined into class like this it's better to do this:
class Derived : Base
{
typedef Base $$;
}
EDIT: I misread your question. This would be an answer to the question whether you can split header-files. It doesn't help you to avoid using LongClassName::-syntaxes, sorry.
The simple answer: You can split up c++-file, but you can not split up header-files.
The reason is quite simple. Whenever your compiler needs to compile a constructor, it needs to know exactly how many memory it needs to allocate for such an object.
For example:
class Foo {
double bar; //8 bytes
int goo; //4 bytes
}
new Foo() would require the allocation of 12 bytes memory. But if you were allowed to extend your class definitions over multiple files, and hence split header files, you could easily make a mess of this. Your compiler would never know if you already told it everything about the class, or whether you did not. Different places in your code could have different definitions of your class, leading to either segmentation faults or cryptic compiler errors.
For example:
h1.h:
class Foo {
double bar; // 8 bytes
int goo; // 4 bytes
}
h2.h:
#include "h1.h"
class Foo {
double goo; // 8 bytes
} // we extend foo with a double.
foo1.cpp:
#include "foo1.h"
Foo *makeFoo() {
return new Foo();
}
foo2.cpp:
#include "foo2.h"
void cleanupFoo(Foo *foo) {
delete foo;
}
foo1.h:
#include "h1.h"
Foo *makeFoo();
foo2.h:
#include "h1.h"
#include "h2.h"
void cleanupFoo(Foo *foo)
main.cpp:
#include foo1.h
#include foo2.h
void main() {
Foo *foo = makeFoo();
cleanupFoo(foo);
}
Carefully check what happens if you first compile main.cpp to main.o, then foo1.cpp to foo1.o and foo2.cpp to foo2.o, and finally link all of them together. This should compile, but the makeFoo() allocates something else then the cleanupFoo() deallocated.
So there you have it, feel free to split .cpp-files, but don't split up classes over header files.
I am trying to make functions repository. I have created four files:
Function.hpp, Function.cpp, FunctionsRepository.hpp, FunctionsRepository.cpp
I want to keep pointers to functions in vector of pointers.
//FunctionsRepository.hpp
#ifndef FUNCTIONSREPOSITORY_HPP
#define FUNCTIONSREPOSITORY_HPP
#include <vector>
using namespace std;
class FunctionsRepository {
private:
static vector<double *> pointerToFunctions;
public:
static void addFunction(double * wsk);
};
#endif
//FunctionRepository.cpp
#include "FunctionsRepository.hpp"
void FunctionsRepository::addFunction(double * wsk) {
pointerToFunctions.push_back(wsk);
}
//Functions.hpp
#ifndef FUNCTIONS_HPP
#define FUNCTOINS_HPP
#include "FunctionsRepository.hpp"
int constFunction(int numberOfVehicles);
void linearFunction();
void stepFunction();
#endif
//Funcctions.cpp
#include "Functions.hpp"
double constFunction(double numberOfVehicles){
return numberOfVehicles/2;
}
double (*funcConstant)(double) = constFunction;
//ERROR HERE
FunctionsRepository::addFunction(funcConstant);
I want to add new functions to program as easily as its possible and use it leater in other parts of program.
But I dont get it. Why i am getting this error. The addFunction() method is static, that means I can use it in other classes or parts of program. Vector is static to make sure that is the only one copy for whole program.
Use function wrapper. std::function can stores callable objects. So, your code will contain something like this:
class FunctionsRepository {
private:
// void() - function prototype
static std::vector<std::function<void()>> pointerToFunctions;
public:
static void addFunction(std::function<void()> wsk)
{
pointerToFunctions.push_back(wsk);
}
};
for more information consult official documentation: http://en.cppreference.com/w/cpp/utility/functional/function
I solved It. I received an error because I was calling the FunctionsRepository::addFunction(funcConstant); expression out of any scope. I just created new function to execute this command and thats all.
I saw this question and I tried to do as the answer to that question said. To use the extern keyword in the header file to define an array and then declare it outside of that namespace or class in a other cpp file.
It didn't work for me really, I'm not sure if it because I'm using a void pointer array (i.e void* array[]) or if it's just my ignorance that prevents me from seeing the problem.
This is the shortest example I can come up with:
[cpp.cpp]
#include "h.h"
void main(){
void* a::b[] = {
a::c = a::d(1)
};
}
[h.h]
namespace a{
struct T* c;
struct T* d(int e);
extern void* b[];
}
So the problem is that I receive the error:
IntelliSense: variable "a::b" cannot be defined in the current scope
And I have no clue why that is.
First, you should declare main() as int ! See here why.
Declaring your array as extern in a namespace means that it belongs to the namespace but is defined somewhere ele, normally in a separate compilation unit.
Unfortunately, in your main(), you try to redefine the element as a local variable. This explains the error message you receive.
You shoud do as follows:
#include "h.h"
void* a::b[] { a::c, a::d(1) }; // global variable belonging to namespace
int main() // int!!!
{
/* your code here */
}
The code will compile. The fact that a::b[] is defined in the same compiling unit is accepted. But the linker will complain because a::d(1) is a call to the function d returning a pointer to a struct, and this function is defined nowhere.
Therfore you should also define this:
namespace a {
struct T* d(int e)
{
return nullptr; // in reality you should return a pointer to struct T
}
}
Interestingly, struct T does not need to work for this code to compile and link.
Is there a way to avoid the Graph:: repetition in the implementation file, yet still split the class into header + implementation? Such as in:
Header File:
#ifndef Graph_H
#define Graph_H
class Graph {
public:
Graph(int n);
void printGraph();
void addEdge();
void removeEdge();
};
#endif
Implementation File:
Graph::Graph(int n){}
void Graph::printGraph(){}
void Graph::addEdge(){}
void Graph::removeEdge(){}
I'm guessing this is to avoid lots of "unnecessary typing". Sadly there's no way to get rid of the scope (as many other answers have told you) however what I do personally is get the class defined with all my function prototypes in nice rows, then copy/paste into the implementation file then ctrl-c your ClassName:: on the clip board and run up the line with ctrl-v.
If you want to avoid typing the "Graph::" in front of the printGraph, addEdge etc., then the answer is "no", unfortunately. The "partial class" feature similar to C# is not accessible in C++ and the name of any class (like "Graph") is not a namespace, it's a scope.
No there's not. Not directly at least. You could go for preprocessor tricks, but don't do it.
#define IMPL Graph::
IMPL Graph(int n){}
void IMPL printGraph(){}
void IMPL addEdge(){}
void IMPL removeEdge(){}
Also, you shouldn't even want to do it. What's the point. Besides it being a C++ rule, it lets you know you're actually implementing a member function.
One option is using. If you have method definitions which are in a cpp file that never gets #included, then using is safe (doesn't affect other files):
foo.h:
class FooLongNameSpecialisationsParamaters
{
int x_;
public:
int Get () const;
void Set (int);
};
foo.cpp:
#include "foo.h"
using Foo = FooLongNameSpecialisationsParamaters;
int Foo::Get () const
{
return x_;
}
void Foo::Set (int x)
{
x_ = x;
}
main.cpp:
#include "foo.h"
int main ()
{
//Foo foo; <-- error
FooLongNameSpecialisationsParamaters foo;
return 0;
}
No, there is no way to avoid it. Otherwise, how would you know if a given function definition is for a class function or for a static function?
If you are asking if you can define a member function such as Graph::printGraph without specifying the class name qualification, then the answer is no, not the way that you want. This is not possible in C++:
implementation file:
void printEdge(){};
The above will compile just fine, but it won't do what you want. It won't define the member function by the same name within the Graph class. Rather, it will declare and define a new free function called printEdge.
This is good and proper, if by your point of view a bit of a pain, because you just might want two functions with the same name but in different scopes. Consider:
// Header File
class A
{
void foo();
};
class B
{
void foo();
};
void foo();
// Implementation File
void foo()
{
}
Which scope should the definition apply to? C++ does not restrict you from having different functions with the same names in different scopes, so you have to tell the compiler what function you're defining.
//yes it is possible using preprocessor like this:
#define $ ClassName //in .cpp
void $::Method1()
{
}
//or like this: in the header .h:
#undef $
#define $ ClassName'
// but you have to include the class header in last #include in your .cpp:
#include "truc.h"
#include "bidule.h" ...
#include "classname.h"
void $::Method() { }
//i was using also
#define $$ BaseClass
//with single inheritance than i can do this:
void $::Method()
{
$$::Method(); //call base class method
}
//but with a typedef defined into class like this it's better to do this:
class Derived : Base
{
typedef Base $$;
}
EDIT: I misread your question. This would be an answer to the question whether you can split header-files. It doesn't help you to avoid using LongClassName::-syntaxes, sorry.
The simple answer: You can split up c++-file, but you can not split up header-files.
The reason is quite simple. Whenever your compiler needs to compile a constructor, it needs to know exactly how many memory it needs to allocate for such an object.
For example:
class Foo {
double bar; //8 bytes
int goo; //4 bytes
}
new Foo() would require the allocation of 12 bytes memory. But if you were allowed to extend your class definitions over multiple files, and hence split header files, you could easily make a mess of this. Your compiler would never know if you already told it everything about the class, or whether you did not. Different places in your code could have different definitions of your class, leading to either segmentation faults or cryptic compiler errors.
For example:
h1.h:
class Foo {
double bar; // 8 bytes
int goo; // 4 bytes
}
h2.h:
#include "h1.h"
class Foo {
double goo; // 8 bytes
} // we extend foo with a double.
foo1.cpp:
#include "foo1.h"
Foo *makeFoo() {
return new Foo();
}
foo2.cpp:
#include "foo2.h"
void cleanupFoo(Foo *foo) {
delete foo;
}
foo1.h:
#include "h1.h"
Foo *makeFoo();
foo2.h:
#include "h1.h"
#include "h2.h"
void cleanupFoo(Foo *foo)
main.cpp:
#include foo1.h
#include foo2.h
void main() {
Foo *foo = makeFoo();
cleanupFoo(foo);
}
Carefully check what happens if you first compile main.cpp to main.o, then foo1.cpp to foo1.o and foo2.cpp to foo2.o, and finally link all of them together. This should compile, but the makeFoo() allocates something else then the cleanupFoo() deallocated.
So there you have it, feel free to split .cpp-files, but don't split up classes over header files.