I want to reimplement a library of which I have the header file.
I would prefer not to change the .h file since that would require changes in the programs that use the library (plus some legal reasons).
EDIT: I also cannot change the code that uses the library and instantiates class X!
the lib.h defines a class X (simplified version):
class X
{
public:
bool Function(BOOL q, INT p);
BOOL a;
INT b;
};
(BOOL and INT are just some datatypes used by the library, these classes wrap a primitive data type of bool and int).
I implemented this class in my_lib_implementation.cpp:
bool X::Function(BOOL q, INT p)
{
return true;
}
The .h file does not define a constructor, so this means that there is an implicit constructor (right?).
Problem is, I need to initialise the variables a and b for my implementation of Function(BOOL q, INT p) to work correctly.
However if I add the following, I get compile errors ("error: definition of implicitly-declared 'X::X()'", gcc 4.4):
X::X()
{
a=true;
b=0;
}
Is it possible to overload the constructor through some magic that I do not know about? Are there other options for initializing the variables?
There is a an implementation of the library (that I can't use), so it seems like it should be possible somehow?
I only just started programming C++ this week (I do have extensive experience with other languages), so this problem is probably just my lack of basic knowledge.
Hope you guys can help me out!
No, it's not possible, the compiler-generated default constructor cannot be overloaded.
You can however initialize the members with the following syntax:
X x = {true, 0};
There isn't really a way to directly do what you're asking. (Provide a default constructor without declaring it in the class.)
The closest you can come to this is to also redefine the BOOL and INT classes, assuming those have defined default constructors. If they have, then you can change the meaning of the default to whatever you want.
Alternately, you could completely change the behavior of the function. You can add members to the class, including for example something to keep track of whether the function has been called yet, or how many times, etc. Or you could define your own betterthanX member and just forward the function calls to the member, and then copy out the results back into the members of the real X class.
A very dirty hack could be to define a preprocessor macro just before including the library header file that changes X to X_. You can then define your own X that inherits from X_ and defines whatever constructor you like. You should #undef the macro after the #include. Don't blame me if you run into insidious bugs.
Related
I am working on a codebase that is not my own, that has the following layout:
object.h:
// Objects are defined
// #include "tickets.h" (functions to access the objects)
// An access-handler object is defined
I want to introduce a class that knows about the objects, can be accessed from functions in tickets.h, but can also use the access-handler object. The functions are separate, i.e. class functions that are called in tickets.h do not use the access-handler (I wouldn't know where to start if that weren't the case).
Therefore my class needs to be defined before tickets.h, but some of its functions need to be defined after the access-handler. Is there a way to do this without splitting it up into two header files something like the following:
// Objects are defined
// -- include declaration of class, and definition of functions that tickets.h needs
// #include "tickets.h"
// An access-handler object is defined
// -- include functions of class that need the access-handler
This seems very messy splitting things up like this into two separate files, I was hoping to keep everything contained.
Thanks for any help, I clearly only have a very rudimentary understanding of declarations/definitions in c++.
EDIT: If I use forward declaration and include it before tickets.h (with the class declared in mynewclass.h and functions defined in mynewclass.cc) will mynewclass.cc be able to use objects declared after the inclusion of mynewclass.h? Namely the access-handler object.
EDIT2: Something like this:
object.h:
class obj { // definition }
#include "tickets.h"
class obj_handler {
public void handle { // code }
}
tickets.h:
void do_something(obj o){
communicator.foo();
}
My object (communicator):
class communicator {
public:
void foo() { // code }
void bar() { // use handle() from obj_handler }
}
As you can see, my communicator needs to be used in tickets.h, but can't be defined until after obj_handler. So where should I include it?
If I correctly understand your question - you can use forward declaration to solve this problem. This will allow you to declare some class before defining it's methods. For example:
// this is forward declaration of class A, no definition provided
class A;
class B
{
// uses A
A * a_;
};
// class A definition
class A
{
// may use class B now
B * b_;
};
I'm not quite sure whether I understand this right and don't have enough reputation here yet to make this a comment, so let me try to answer your question this way, please feel free to follow up if I'm guessing wrong:
I believe what you are referring to is an entire class definition, i.e., one including all function definitions within the class declaration. Other than that, it is not very common to see object definitions followed by preprocessor directives. What is typical though is a forward declaration of functions and a class prototype.
So, for example, you could declare in some header.h:
class C
{
public:
void method1(void);
int method2(void);
};
And in some implementation.cpp the definition of the functions like:
void C::method1(void) { /*...*/ }
In the other file preceded in the inclusion chain by your access-handler you then define the other function:
int C::method2(void) { /*...*/ }
What do you mean by access-handler, by the way?
Oh, and your linker likely will yell somewhat at you if you do function definition in a header file.
With regard to your addenda: everywhere you put a forward declaration, loosely speaking, the compiler will insert a copy of the declaration in question, consider it a soft link in the context of file systems. There are negative implications associated with it, like increased duration and the memory load of compilation if you have many forward declarations of the function signature or class. It's impossible to tell whether this will word in your particular situation since only you know the actual code in question. But most likely it would work.
Take a look at these pages:
http://en.wikipedia.org/wiki/Forward_declaration
When can I use a forward declaration?
I got 17 integer constants that I'd like to have as private in my class. Is it really necessary to use initialization list?
I read somewhere that I can assign values to constants in the header file, but it doesn't seem to work. I get this error message:
sorry, unimplemented: non-static data member initializers
Is it really necessary to use initialization list?
In modern (2011-era) C++, no. In older versions of the language, yes.
Your error message is apologising that your compiler doesn't support the new initialisation syntax for non-static members yet. Assuming you're using GCC (since I recognise that error from that compiler), then according to this page you'll need to upgrade to at least version 4.7 for that feature.
Alternatively, since they're private and constant, you might consider moving them out of the class into a local namespace in the class's implementation file. Of course, that will only work if you don't need to access them from any inline member functions.
Finally, if they have the same values for all instances of the class (which is likely, since they are const and you're able initialise them independently of the constructor arguments), you could declare them static. Then they can be initialised in their declaration (although older compilers might only allow that if they have an integer type). However, if they are odr-used (roughly speaking, if you need to take a pointer or reference to them), then they will also need to be defined in exactly one source file.
.h:
class MyClass {
public:
MyClass();
~MyClass();
int doSomething();
private:
const int m_newint = 1;
const int m_dosomething = 2;
};
.cc:
MyClass::MyClass() {}
MyClass::~MyClass() {}
int MyClass::doSomething() {
return m_dosomething;
}
Is valid C++11 code, make sure your compiler is set to -std=c++11 to use the
feature.
So I was learning about classes and I stumbled upon something I found was quite awkward to me.
class Nebla
{
public:
int test()
{
printout();
return x;
}
void printout()
{
printout2();
}
private:
int x,y;
void printout2()
{
cout<<"Testing my class";
}
};
I found that in a class I can use functions before I declare them (prototype them)
You can see I used printout() , printout2() before decleration.
And I can use variables also before declaring them
You can see I did return x; before declareing x.
Why can I use functions and variables in classes before declaration but outside the class if I do that, I get an error?
Thanks
Good question; I've relied on that feature for years without thinking about it. I looked through several C++ books to find an answer, including Stroustrup's The C++ Programming Language and The Annotated C++ Reference Manual, but none acknowledge or explain the difference. But, I think I can reason through it.
The reason, I believe, that your example works is that the bodies of your test and printout aren't truly where they appear in your file. The code
class MyClass {
void someFun() {
x = 5;
}
int x;
};
...which appears to violate the rule of having to declare variables before you use them, is actually equivalent to:
class MyClass {
void someFun();
int x;
};
void MyClass::someFun() {
x = 5;
}
Once we rewrite it like that, it becomes apparent that the stuff inside your MyClass definition is actually a list of declarations. And those can be in any order. You're not relying on x until after it's been declared. I know this to be true because if you were to rewrite the example like so,
void MyClass::someFun() {
x = 5;
}
class MyClass {
void someFun();
int x;
};
...it would no longer compile! So the class definition comes first (with its complete list of members), and then your methods can use any member without regard for the order in which they're declared in the class.
The last piece of the puzzle is that C++ prohibits declaring any class member outside of the class definition, so once the compiler processes your class definition, it knows the full list of class members. This is stated on p.170 of Stroustrup's The Annotated C++ Reference Manual: "The member list defines the full set of members of the class. No member can be added elsewhere."
Thanks for making me investigate this; I learned something new today. :)
Just to make it clear, this is required by the C++ Standard, not just the way several compilers handle class definitions.
N3242 3.3.7:
The potential scope of a name declared in a class consists not only of the declarative region following the name's point of declaration, but also of all function bodies, brace-or-equal-initializers of non-static data members, and default arguments in that class (including such things in nested classes).
The reason you are able to do this is because by the time you call test, printout or printout2, they will have already been created. If you call the function outside the arbitrary function before it's implementation, then you'll get an error.
Think of class member-functions as being asynchronous with the flow of evaluation of the rest of the class. This won't work with stand alone functions, but you can access data members that haven't been instantiated yet. I'm not completely sure why we are able to do this, but I think it has to do with instantitation of the class object.
Besides Philip's good response, Stroustrup gives a nice explanation of Name Lookup Rules in The Design and Evolution of C++. This is described in "6.3 Clarifications". In 6.3.1.1, "The ARM Name Lookup Rules", he mentions 2 rules defined in the ARM:
[1]The type redefinition rule:A type name may not be redefined in a class after it has been used there.
[2] The rewrite rule: Member functions defined inline are analyzed as if they were defined immediately after the end of their class declarations.
So in your case it would apply the rewrite rule (as Philip deduced), that's why you can forward reference those class members.
This book may be mainly of historical interest (it's written in '94), but I think those rules are applied the same way today.
Why can I use functions and variables in classes before declaration
This is because the body of a member function is a complete-class context of a class, as mentioned in the quoted statements below:
From class.mem.general#6:
6. A complete-class context of a class is a:
function body ([dcl.fct.def.general]),
default argument,
noexcept-specifier ([except.spec]), or
default member initializer
within the member-specification of the class.
This means that the usage of printout inside member function test and the usage of printout2 inside member function printout is allowed here even though those members appear later when writing the class definition.
Before switching to C++, we found the initialization language element in Delphi extremely useful. It allowed you to have code in each unit which would be called when the program was started, so you could initialize various elements of that unit.
This does in our opinion make things easier and helps to keep the code clean.
So why is there no initialization and finalization in C++?
What are our options for replacements of this language feature in C++?
The equivalent C++ feature is constructors and destructors for file-scope/global objects. For instance:
#include <iostream>
using std::cout;
struct X {
X() { cout << "X::X()\n"; }
~X() { cout << "X::~X()\n"; }
};
static X x;
int main() { cout << "main()\n"; return 0; }
will output
X::X()
main()
X::~X()
when run.
It is generally considered unwise to use this feature, because you have no control whatsoever over the order in which these constructors and destructors are executed, which means things may get initialized before their dependencies, producing hard-to-debug crashes.
In C++ constructor/destructor pairs are generally used for this sort of thing. Be careful when using static objects, however. Two things you should read if you want to do this:
What's the "static initialization order fiasco"?
How do I prevent the "static initialization order fiasco"?
Question 1: why isn't there a keyword?
No-one apart from Stroustrup or the committee members can really answer why C++ is how it is, but we can speculate, probably that it wasn't considered important enough for a keyword. The C++ standard does talk about order of initialization, such as for objects but the order is not strictly defined and left to the implementation. Here's one quote (3.6.2/3):
It is implementation-defined whether
or not the dynamic initialization
(8.5, 9.4, 12.1, 12.6.1) of an object
of namespace scope is done before the
first statement of main. If the
initialization is deferred to some
point in time after the first
statement of main, it shall occur
before the first use of any function
or object defined in the same
translation unit as the object to be
initialized
Question 2: how to achieve the equivalent of the Delphi initialization and finalization keywords?
There are two options. The first has been mentioned by other posters and I don't want to copy their answers: declare an object in a certain scope (translation unit or namespace) and its constructor and destructor will be called 'sometime'; do work there.
Note that the order of this is implementation-defined, so you're already in uncertain territory.
The second option is also compiler dependent. You're using Delphi, so am I right in thinking you're using C++ Builder to compile your C++ code? If so, C++ Builder and some other compilers support the #pragma startup and #pragma exit pragmas. These pragmas call a method at a certain time when your program is starting up or shutting down.
Personally I find this a neater solution, for two reasons:
It specifies exactly when something
will occur and I can see it written
down in code
It allows you to call a
function, instead of using a
constructor or destructor. This is
aesthetically cleaner and lets you write, say,
initialization() and finalization() methods which
perform your work. This probably gets you as close to the Delphi syntax as you can get.
You can use these pragmas to call a procedure (which takes no parameters and returns void) and also optionally specify when it should occur, using a number between 64 and 255. You need to do this only if the order of initialization or finalization matters. A higher number is called first and priorities of 0-63 are reserved. For example:
void initialization(void) { foo = 3; bar = 5; /* Do useful work here */ }
#pragma startup initialization 200
void finalization(void) { foo = 0; bar = 0; /* Do useful work here */ }
#pragma exit finalization 200
The call chain is managed by the linker and you can run into issues if you use more compiler-specific constructs, such as weak packaging, but in general this is the technique I would recommend.
Class have constructors and destructors that you can use to intialize and clean up.
I think the closest you get to "code units" in C++ is classes.
Write a class with a constructor (initialization code) and a destructor (finalization code). Declare a singleton instance of this class; the constructor will be called at startup, and the destructor before the program shuts down.
Typically, it's viewed as a code smell in C++ to have global state that needs construction or destruction, and even if you did have this, you would just declare a class that does this in it's constructor and define a file-global instance of it.
In C++ you call the constructor (equivalent to your destructor) the same name of you class and the destructor the same name of you class, prefixed with tilde (~):
Class Point {
public:
Point() { }
~Point() { }
}
The closest feature C++ has to what you are use to is static variables (specifically, static member variables).
// A.h
class A
{
public:
private:
static int someValue;
};
// A.cpp
int A::someValue = 2;
The static variable is initialized at program startup. There is no automatic "finalization" procedure for static members (you would have to write your own cleanup function and call it).
I know how to initialize a static member that's not an integer, but I'm wondering, what is the rationale behind the syntax for this? I'd like to be able to just put the value in the class, like you can with an integer member, a la:
class A {
static const int i = 3;
};
I realise this could mean more rebuilding if I change the value since it's a change in the header - but in some cases that's pretty unlikely - and just as bad as changing a #define in the header anyway.
It doesn't seem like something that would be terribly hard for the compiler to understand. Are there technical reasons why it works the way it does? Or is it just a case of the compiler enforcing the good practice of separating the implementation from the definition?
Because that is the class declaration. You don't have any object yet.
You need to actually define the value somewhere --- somewhere specific.
Since it is static it's actually taking up space somewhere. But, since the .H file which has that declaration can be #included in many source files, which one defines holds the actual space it is using? Having the compiler automatically define the space in every object file and having the linker sort it out would be a violation of the "One Definition Rule".
A static class member has linkage, so it needs to be in a source file. Just because you declare it const doesn't mean it really can't change (please look up volatile for example).
This might help you:
class A {
enum { i = 3 }; // use an enum to set a constant value in the class declaration
void f() { int k = int(i); }
}