in a book i am reading to learn basic c++, there is this example:
#include <iostream>
using namespace std;
class Point {
private: // Data members (private)
int x, y;
public: // Member functions
void set(int new_x, int new_y);
int get_x();
int get_y();
};
void Point::set(int new_x, int new_y) {
x = new_x;
y = new_y;
}
int Point::get_x() {
return x;
}
int Point::get_y() {
return y;
}
My question is, is it not possible in c++ to include the definition of the member functions inside the class itself? The above seems quite messy. The book says to define a class member function you should use 'return_type class_name::function(){arguments}. But in C# you can just do it within the same class and it is less code. I haven't been able to find much about properties in c++. Thanks for help.
Although it is possible, it's not really recommended. Actually, the way it's done in your book isn't how it should be done either (and hopefully, later on in the book that will change!). The way you'll see it done 99% of the time (yes, I pulled that number out of my ass) is a class definition in a header file (.h extension) and the definitions in a source file (.cpp extension). The header file will be imported so to speak, into the source file via #include.
You can define the members within the class as such.
class Point {
private: // Data members (private)
int x, y;
public: // Member functions
void set(int new_x, int new_y) {
x = new_x;
y = new_y;
}
int get_x() { return x; }
int get_y() { return y; }
};
However, this isn't a popular style of coding in C++. Most C++ conventions suggest that you separate the implementations (definitions) from the interface (the declarations) in different files (definitions would go into Point.cpp, and declarations would go into Point.h), unless the definitions are very short (like accessors).
You can define functions in the class definition in C++. This will cause them to be inline implicitly but that shouldn't matter because compilers have flexibility in terms of actually inlining. Usually this isn't done because it will increase compile time due to larger amounts of code being processed and the canonical C++ way it to put the method definitions in a separate source file.
class Point
{
private: // Data members (private)
int x, y;
public: // Member functions
void set(int new_x, int new_y)
{ x = new_x; y = new_y; }
int get_x()
{ return x; }
int get_y()
{ return y; }
};
of course you can write
#include <iostream>
using namespace std;
class Point {
private: // Data members (private)
int x, y;
public: // Member functions
void set(int new_x, int new_y)
{
x = new_x;
y = new_y;
}
int get_x()
{
return x;
}
int get_y()
{
return y;
}
};
But whole point is to separate declaration and implementation.
Yes we can Define a function inside a class.it has following advantage.
1)the function which you define inside a class is treated as an "inline" function .
(inline keyword before any function suggest compiler to place body of the definition of the function to where ever that function is been called from at compile time)
2)due to which inline function execute Faster.then normal function.
(remember its totally up to the compiler to make that function inline or not.you cannot force compiler to make it inline)
Most answers point out that it is possible but not recommended, I do not agree with the latter. For simple one-liner accessors it just makes sense to provide them inside the class definition in most cases:
class point {
int x,y;
public:
// ...
int posX() const { return x; }
int posY() const { return y; }
};
As of the setters, it will depend on whether you want to verify any invariant or not. In the former case, you might want to move it to a single translation unit, but even there if the checks are small I would just inline them inside the class definition.
The recommendations for separating declaration and definition of the member methods include things like:
smaller compile time: false, the compiler can parse the accessor trivially, it will not add much more to the parsing
smaller code size: false, if the function is not inlined, then the compiler must generate code for the function call, including calculation of the this pointer and actually perform the call. The inlined accessor will just require the reading of the member which will take less code.
higher compile time coupling: any change in the implementation of the function will require recompilation of all translation units that include the header... True, if you change the function, which for such a simple accessor will not happen.
Related
I have three files -- main, a header and its 'implementation':
// main.cpp
#include "word_indexer.h"
int main() {
WordIndexer wd;
cout << wd.size() << endl;
return 0;
}
// word_indexer.h
class WordIndexer {
public:
int size() const; // declaring a function
};
// word_indexer.cpp
class WordIndexer {
public:
int size() const {return 0;}
};
Building with g++ -o main main.cpp word_indexer.cpp yields
undefined reference to 'WordIndexer::size() const'
Replacing the implementation with
// updated word_indexer.cpp
class WordIndexer {
public:
int size() const;
};
int WordIndexer::size() const {return 0;}
fixes the problem.
I cannot figure out the difference between these word_indexer.cpp and its updated versions, they seem to be identical.
Why does the first variant have linking problems?
There is no need to repeat the definition of the class in its implementation file. Just have it include the header the class is defined in and then define the member functions in the implementation file like:
// word_indexer.cpp
#include "word_indexer.h"
int WordIndexer::size() const {return 0;}
As for why the first variant did not work: Member functions defined in a class are implicitly inline. Thus, their definitions must be present in every translation unit that uses them. This is why this works if you define the member in the class in the header file, but not if you only have the inline definition in another .cpp file.
Here's how it's usually done for classes.
Header (word_indexer.h):
// declare the class and all its methods, member variables, etc.
class WordIndexer {
public:
int size() const; // declaring a function, but not its implementation
};
Implementation (word_indexer.cpp):
// the implementation basically takes the header "skeleton" and fleshes it out;
// to do that, of course, we need the skeleton first
#include "word_indexer.h"
// we don't need to say "class WordIndexer {}" or anything like that,
// because that's already been done in the header we included
// implement the method
int WordIndexer::size() const {return 0;}
In word_indexer.cpp you should have written something like:
int WordIndexer::size() const {return 0;}
That's the actual definition syntax.
And instead of redeclaring WordIndexer in the translation unit, just #include "word_indexer.h".
I currently have two unnamed classes defined in my Foo.h:
class Foo {
public:
Foo();
class {
private:
int x;
int y;
public:
int GetX() { return x; }
int GetY() { return y; }
} Sub1;
class {
private:
int x;
public:
int GetX() { return x; }
} Sub2;
}
This code compiles just fine, and it used like this:
Foo temp;
int Ax, Ay, Bx;
Ax = temp.Sub1.GetX();
Ay = temp.Sub1.GetY();
Bx = temp.Sub2.GetX();
However, now I want to move the member function definitions to the source file.The only way I know to split this class into a header file and source file, is to name the classes:
Foo.h:
class Foo {
private:
class A {
private:
int x;
int y;
public:
int GetX();
int GetY();
};
class B {
private:
int x;
public:
int GetX();
};
public:
Foo();
A Sub1;
B Sub2;
}
Foo.cpp:
int Foo::A::GetX() { return x; }
int Foo::A::GetY() { return y; }
int Foo::B::GetX() { return x; }
This code is not what I want, however, since it is ugly and I didn't want a named class in the first place.
Is it possible to split the class into a header file and source file? Or is this just bad code design?
It is, unfortunately, impossible. ยง9.3/5:
If the definition of a member function is lexically outside its class
definition, the member function name shall be qualified by its
class name using the :: operator.
Since no class name exists, no out-of-class definitions for member functions are possible. The fact that GCC allows decltype-specifiers in this context is a bug.
With gcc at least, you can do the trick using decltype:
int decltype(Foo::Sub1)::GetX() { return x; }
It is not standards compliant, though, as Columbo has already pointed out. So don't blame me, if a future version of gcc refuses to compile this. But we all now, that gcc has never been dogmatic about standards compliance, and that the gcc team has a strong tendency to keep language extensions, if they are both unambigous (which is clearly the case here) and useful to at least some programmers. Over the time, many of these gcc extensions have eventually become part of the standards.
Nonetheless, clang and probably most other compilers refuse this construct with the error message:
'decltype' cannot be used to name a declaration
But even clang can be tricked into accepting the decltype trick. We just need to do a typedef:
typedef decltype(Foo::Sub1) Sub1type;
int Sub1type::GetX() { return x; }
Of course, this is not much different to naming the unnamed classes. The advantage of the typedef solution might still be, that you can hide away the type names inside a private namespace.
How could I make a function only seen by the function that calls it?
define the function I want to hide as private function is not enough, as it could still be seen by other public functions in the class.
Now I use lambda expression to define anonymous function inside function. Is there any better solution?
Aside from using a lambda (which you've rejected), you could implement your function in its own compilation unit, and code the supporting function in an anonymous namespace within that compilation unit.
But that supporting function would be outside the class, so you'd have to pass it all the parameters it needed. That could become unwieldly though no worse than a long lambda capture list.
You can use a function object. For example(you can compile this, even in C++03):
#include <iostream> // only for output
class foo{
int bar(){return 0;} // Only foo can see this
public:
int operator()(){
return bar();
}
};
class baz{
public:
foo do_foo;
};
int main(){
baz a;
std::cout << a.do_foo() << std::endl;
}
the method bar is only visible by a foo.
P.S.: If you need foo to access members of baz, make it a friend.
A simmilar approach to cassiorenan would be to use static class functions and friends.
Something like this:
void Boss();
class Worker {
static void Test(){ return;}
friend void Boss();
};
void Boss(){
Worker::Test();
}
Though why would you want to do this, I don't know.
It is possible to define function inside a function without lambdas. Just define a struct that contains required function. This approach is not much better than using lambda, but at least this is straightforward and works with older compilers too.
int func() {
struct {
int hiddenFunc() {
return 1;
}
} h;
int a = h.hiddenFunc() + h.hiddenFunc();
return a;
}
As a slight variation from cassiorenan's solution, you could use a class containing one public static function (the visible function) and one static private function that could only be called from there. To avoid creation of objects of that class, it is enough to put a private constructor.
EDIT:
Per cassiorenan's comment, I can see that OP really needs methods and not functions. In that case, I would still use a dedicated class in a anonymous namespace to ensure it is not visible from elsewhere (even if my example is single file ...) friend to the class really used. So in below example, bar is the business class that would have a method with an externally hidden implementation (here relay_method), and foo is dedicated to the hidden method called with a pointer to the real object. In real world, the whole anonymous namespace and the implementation of the hidden method should be in the implementation file bar.cpp.
That way, the real implementation function priv_func can only be called from a bar object through bar::relay_method() and foo::bar_func(bar &).
#include <iostream>
class bar;
namespace {
class foo {
private:
static int priv_func(int i) {
return i * i;
}
foo() {}
public:
// only useful if true functions were needed
/* static int pub_func(int i, int j) {
return priv_func(i) + priv_func(j);
}*/
static void bar_func(bar& b);
};
}
class bar {
int x;
int x2;
public:
bar(int i): x(i) {}
void relay_method() {
foo::bar_func(*this);
}
friend class foo;
int getX2() const {
return x2;
}
};
void foo::bar_func(bar& b) {
b.x2 = foo::priv_func(b.x);
}
using namespace std;
int main() {
/* int i = foo::pub_func(3,4);
cout << i << endl;
// foo::priv_func(2); error access to private member of class foo
// foo f; */
bar b(2);
b.relay_method();
cout << b.getX2() << endl;
return 0;
}
I've been playing with the Pimpl idiom and reaping all sorts of benefits from it. The only thing I haven't been too keen on is the feeling I get when I define the functions.
Once in the header (P def)
Once at the top of the .cpp (Impl def)
Once in the middle of the .cpp (Impl Impl)
Once at the lower end of the .cpp (P Impl)
I really enjoy cutting down code disparity and redundancy, and I feel like my code is less than well oiled when I have to add or change functions in even relatively complex Impls in my current project.
My question is, what effective ways are there to imply or template my classes in such a way that if I were to define a new function, I'd only have to write one explicit definition and implementation, and have the rest remain spatially close to the explicits in code; and if I were to change a function, the changes necessary would be as few as possible?
You might consider something along these lines:
An Interface class to minimize repeating declarations. The client will use the PublicImplementation class in their code.
Pimpl.h
#ifndef PIMPL_H_
#define PIMPL_H_
#include <memory> // std::unique_ptr
class Interface
{
public:
virtual ~Interface() {}
virtual void func_a() = 0;
virtual void func_b() = 0;
};
class PublicImplementation
{
// smart pointer provides exception safety
std::unique_ptr<Interface> impl;
public:
PublicImplementation();
// pass-through invoker
Interface* operator->() { return impl.get(); }
};
#endif // PIMPL_H_
Pimpl.cpp
#include "Pimpl.h"
#include <iostream>
class PrivateImplementation
: public Interface
{
public:
void func_a() override { std::cout << "a" << '\n'; }
void func_b() override { std::cout << "b" << '\n'; }
};
PublicImplementation::PublicImplementation()
: impl(new PrivateImplementation)
{
}
And finally this is what the client code does:
Main.cpp
#include "Pimpl.h"
int main()
{
PublicImplementation pi; // not a pointer
pi->func_a(); // pointer semantics
pi->func_b();
}
Let's postulate your header starts something like this:
class X
{
public:
...la de dah...
private:
struct Impl;
Impl* p_impl_;
};
Then when you add functions you have a choice to make:
do you have the X member function definition implement the logic, referring to p_impl_-> things all over the place, or
return p_impl->same_fn(all_the_args); and keep the logic inside the Impl class?
If you choose 1. then you end up with a function declaration in the header, and a (slightly messier than usual) definition in the matching implementation file.
If you choose 2. then you end up with a function declaration in the header file, a wrapping/forwarding definition in the matching implementation file, and at a minimum a definition in the Impl structure (I tend not to define the functions outside the Impl class definition - it's an implementation detail and the interface is not public anyway).
There is no generally desirable way to improve on this situation (i.e. macro hackery and extra code-generation scripts in your build process may occasionally be warranted, but very rarely).
It may not matter a whole heap, though it may be of interest that a variation on the second approach is to first implement a class that doesn't use the pimpl idiom (complete with proper header and optionally inline functions), you can then wrap it with a pimpl management object and forward functions to it, and in that way you keep the freedom to have some code somewhere some day decide it wants to use the functionality without using the pimpl wrapper, perhaps for improved performance / reduced memory usage at the cost of the recompilation dependency. You can also do this to make use of a specific instantiation of a template without exposing the template's code.
To illustrate this option (as requested in a comment), let's start with a silly non-pimpl class X in its own files, then create a Pimpl::X wrapper (the use of namespace and the same class name is entirely optional but facilitates flipping client code to use either, and a reminder - this isn't meant to be concise, the point here is to let a non-pImpl version be usable too):
// x.h
class X
{
public:
int get() const { return n_; } // inline
void operator=(int); // out-of-line definition
private:
int n_;
};
// x.c++
#include <x.h>
void X::operator=(int n) { n_ = n * 2; }
// x_pimpl.h
namespace Pimpl
{
class X
{
public:
X();
X(const X&);
~X();
X& operator=(const X&);
int get() const;
void operator=(int);
private:
struct Impl;
Impl* p_impl_;
};
}
x_pimpl.c++
#include <x.h>
namespace Pimpl
{
struct X::Impl
{
::X x_;
};
// the usual handling...
X() : p_impl_(new Impl) { }
X(const X& rhs) : p_impl(new Impl) { p_impl_->x_ = rhs.p_impl_->x_; }
~X() { delete p_impl_; }
X& operator=(const X& rhs) { p_impl_->x_ = rhs.p_impl_->x_; return *this; }
// the wrapping...
int X::get() const { return p_impl_->x_.get(); }
void X::operator=(int n) { p_impl_->x_ = n; }
}
If you opt for the above variation on 2, which makes the "implementation" a usable entity in it's own right, then yes - you may end up with 2 declarations and 2 definitions related to a single function, but then one of the definitions will be a simple wrapper/forwarding function which is only significantly repetitive and tedious if the functions are very short and numerous but have lots of parameters.
There's no requirement to treat the IMPL object to the same rules & standards as an object declaration in the .h file. By allowing member variables to be public (via a struct declaration), you don't need to implement an unnecessary wrapper layer. This is generally safe, since only the .cpp file has access to IMPL anyway.
Consider the following code that achieves the benefits of the PIMPL idiom without unnecessary code duplication:
// x.h
class X {
public:
X();
~X();
X(const X&) = delete;
X& operator =(const X&) = delete;
void set(int val);
int get() const;
private:
struct IMPL;
IMPL* impl;
};
// x.cpp
#include "x.h"
struct X::IMPL {
int val;
};
X::X() : impl(new IMPL) {}
X::~X() { delete impl; }
void X::set(int val)
{
impl->val = val;
}
int X::get() const
{
return impl->val;
}
// main.cpp
#include <iostream>
#include "x.h"
int main (int, char *[])
{
X x;
x.set(10);
std::cout << x.get() << std::endl;
return 0;
}
I'm just going to start by sumarizing to make sure I understand: You like the benefits of using pimpl, but dislike the amount of boilerplate code when adding or modifying functions?
In a nutshell, there is no template magic you can use to eliminate this boilerplate, but there are things to consider here as well:
You write code only once but read it many times, and you have at your disposal a variety of copy-paste capabilities. Initially creating the function isn't the majority of the time you will spend on this class. Compiling and maintaining is where your time will be spent.
Be sure to keep the public class API as simple as possible. The fewer functions you have in the public API the less boilerplate you have to write. You can make as many functions as you like in the impl and y ou only have to modify them there.
If you find yourself changing the public class API many many times, you might wish to slightly adjust your design process. Spend ten more minutes up front looking at/writing down use cases and you may reduce your API changes by 90%.
I would like to be able to achieve something like this:
class Zot
{
namespace A
{
static int x;
static int y;
}
}
I am working with a legacy system that uses code generation heavily off a DB schema, and certain fields are exposed as methods/variables in the class definition. I need to add a few extra static variables to these classes and would like to guarantee no clashes with the existing names.
The best I have come up with is to use another struct to wrap the statics as if it were a namespace:
class Zot
{
struct A
{
static int x;
static int y;
}
}
Is there a better way?
Update:
An extra requirement is to be able to access these from a template elsewhere
e.g.
template<class T>
class B
{
void foo() { return T::A::x; }
};
So putting them in a separate class won't work
Really the inner struct is your best bet. Another possibility would be to use a typedef to bring in a class of statics. This works well for code generation in that you can separate the extras from the generated code:
In the generated file that doesn't care at all what's in Zot_statics:
class Zot_statics;
class Zot
{
public:
typedef Zot_statics A;
int x; // This is ok
};
In a hand-maintained header for when you need to access x and y:
class Zot_statics
{
public:
static int x;
static int y;
};
In a hand-maintained cpp file:
int Zot_statics::x;
int Zot_statics::y;
And your template should work just fine with Zot::X referring to the instance variable X on Zot, and Zot::A::x refering to the static variable.