//function declerations
void func_A();
void func_B();
void func_SubA();
//main
int main(){ ... }
//function definitions
void func_A(){ ... }
void func_B(){ ... }
void func_SubA(){ ... }
What is the best way of ensuring that func_SubA() can only be called inside of func_A()?
I would like to receive a compiler error if func_B() attempted to call func_SubA().
You can declare the functions you want to restrict access to as private members of a class and then use friendship to grant access.
class Balloon
{
private: // private is the default. we just want to be explicit
friend void Ken();
friend void Barbie();
static void Pop();
};
void Ken() {
Balloon::Pop(); // We are allowed to pop it!
}
void Barbie() {
Balloon::Pop(); // We are allowed to pop it too!
}
void Jack() {
Balloon::Pop(); // Access Denied! we must be in a time out!
}
Another way is placing the definition of func_A() and func_SubA() in a different translation unit (cpp file) and making func_SubA() invisible outside this file by either making it static or placing it in an anonymous namespace:
// FILE main.cpp
//function declarations: possibly in a header file
void func_A();
void func_B();
// don't declare func_SubA() here
int main(){ /* ... */ }
void func_B(){ /* ... */ } // could also have its onw cpp file
// EOF main.cpp
// FILE func_A.cpp
static void func_SubA(){ /* ... */ }
/* or
namespace {
void func_SubA(){ ... }
}
*/
void func_A(){ /* calls func_SubA() */ }
// EOF func_A.cpp
Another way, as suggested by JesseTG and which I'm just making clear here, is using lambda expressions:
//function declarations
void func_A();
void func_B();
// don't declare func_SubA();
int main(){ /* ... */ }
//function definitions
void func_A(){
// define func_SubA through a lambda
auto func_SubA = [](){ /* the body of func_SubA */ };
// ...
func_SubA(); // calls func_SubA()
// ...
}
void func_B(){ /* ... */}
You can either do this the usual object-oriented way (private methods, etc.) or you can use lambda functions, which is a new feature in C++11. You can read up on them here or here, they're not difficult to use. Lambda functions allow you to access variables that are local to whatever block of code holds them.
Function declarations can be local, too. If you put the forward declaration for func_SubA inside funcA(), you should be good.
Related
I'm trying to create a dummy function inside of a class, whichs' body will be changed later in int main(). And then I'd like to call this body changed func in the class. Is there a way to achieve this?
Something like this:
class Animation {
public:
//Don't know what to write at the next line
function<void>/*?*/ whenCompleted = []() mutable { /* Dummy func. */ };
.
.
.
void startAnimation() { /* Do stuff, then */ animationEnded(); }
void animationEnded() { whenCompleted(); }
}score;
int main(){
score.whenCompleted = { /* new body for whenCompleted() */ }
score.startAnimation();
}
You basically have the right idea
#include <functional>
#include <iostream>
class Animation
{
public:
std::function<void()> whenCompleted;
void startAnimation() { animationEnded(); }
void animationEnded() { whenCompleted(); }
};
int main()
{
Animation score;
score.whenCompleted = [](){ std::cout << "all done"; };
score.startAnimation();
}
Will output
all done
You could also add a constructor for Animation that accepts a function to initialize whenCompleted with
Animation(std::function<void()>&& onCompleted) : whenCompleted(onCompleted) {}
which would modify main to
int main()
{
Animation score{[](){ std::cout << "all done"; }};
score.startAnimation();
}
I have several c++ programs that are all reading a YAML configuration file in /etc/foo/config.yml. I have written a function that reads the config from the file
YAML::Node load_config();
(using the yaml-cpp library).
I would like this configuration to be loaded once, at the beginning of the main() function of my program, and then accessible everywhere as some kind of global variable.
Currently, many of my functions have extra parameters that are just values read from the configuration file. It could be avoided by having this global configuration, making my function definitions and calls much simpler and readable.
Side note: I am also using OpenMP for distributing computation, which means that the configuration must be accessible to all parallel processes.
Could someone give a tiny example of what this would look like when done the right way?
Thanks!
here's one way. It's a variation on the idea of the schwartz counter to manage a global singleton (for example, std::cout itself)
// globals.hpp
#include <istream>
struct globals_object
{
globals_object()
{
// record number of source files which instanciate a globals_object
++init_count_;
}
~globals_object()
{
// The last source file cleans up at program exit
if(--init_count_ == 0)
{
if (pimpl_)
{
delete pimpl_;
}
}
}
// internal implementation
struct impl
{
void load(std::istream& is)
{
// do loading code here
}
int get_param_a() const {
return a_;
}
int a_;
};
// (re)load global state
void load(std::istream&& is)
{
if (pimpl_) delete pimpl_;
pimpl_ = new impl;
pimpl_->load(is);
}
// public parameter accessor
int get_param_a() const {
return get_impl().get_param_a();
}
private:
static int init_count_;
static impl* pimpl_;
static impl& get_impl()
{
return *pimpl_;
}
};
// one of these per translation unit
static globals_object globals;
// globals.cpp
// note - not initialised - will be zero-initialised
// before global constructors are called
// you need one of these in a cpp file
int globals_object::init_count_;
globals_object::impl* globals_object::pimpl_;
// main file
// #include "globals.hpp"
#include <fstream>
int main()
{
globals.load(std::ifstream("settings.yml"));
}
// any other file
// #include "globals.hpp"
#include <iostream>
void foo()
{
std::cout << globals.get_param_a() << std::endl;
}
I am just starting an assignment and am beginning with defining the functions of the class in the "Distance.h" tab and although I am pretty sure my functions are initialized correctly, I am still getting compiler errors saying that "definition not found." I used an online tutor and he ran it on his computer and did not get any errors, although he was not any further help with me fixing this issue. Does anyone know what I am supposed to do in this situation as this is my only computer or if anyone can tell me if I actually am just coding wrong.
Here is my "Distance.h":
#pragma once
class Distance
{
private:
long length;
public:
// Transformers
void setLength(long newLength);
void setFeet(int newFeet);
// Observors
long getLength();
int getFeet();
int getInches();
double getLengthInFeet();
};
You have to define your class methods. For instance:
#pragma once
class Distance
{
private:
long length;
public:
//Transformers
void setLength(long newLength){
// TODO: define your method here
// For instance: length = newLength;
}
void setFeet(int newFeet){
// TODO: define your method here
}
//Observors
long getLength(){
// TODO: define your method here
}
int getFeet(){
// TODO: define your method here
}
int getInches(){
// TODO: define your method here
}
double getLengthInFeet(){
// TODO: define your method here
}
};
I've read of similar problems to this, but the solutions provided didn't work for me so.
I want to call a function that exists in another class located in a different .cpp file. I don't want to create an instance of the object, I just want to use the function.
My code that tries to call the function:
switch (option)
{
case 1:
cout << "\nDoing stuff\n\n" ;
Controller::AlbumOps SayHey();
//SayHey should have run but isn't working
break;
And the function I'm trying to call:
#include "Menu.hpp"
#include "Album.hpp"
#include "stdio.h"
#include "AlbumOps.hpp"
#include <iostream>
using namespace std;
namespace Controller
{
static void Controller::AlbumOps::SayHey ()
{
cout << "Hey\n";
}
}
When I execute the code, the Hey is never printed. I thought the solution was to make the function static but that hasn't worked for me.
The call should be
Controller::AlbumOps::SayHey();
// ^^
// double-colon
You should put static on the in-class function declaration, not the out-of-class function definition (where it means something completely different, "internal linkage"). That is:
in the header (AlbumOps.hpp):
// ...
namespace Controller
{
class AlbumOps {
public:
// ...
static void SayHey(); // Note: 'static' here
};
}
// ...
and in the implementation file (AlbumOps.cpp): either:
// ...
void Controller::AlbumOps::SayHey() // Note: no 'static'
{
cout << "Hey\n";
}
// ...
or:
// ...
namespace Controller
{
// ...
void AlbumOps::SayHey() // Note: no 'static', no repeated 'Controller::'
{
cout << "Hey\n";
}
// ...
}
// ...
(For the record, what you current
Controller::AlbumOps SayHey();
// ^
// space
does is locally declare a function named SayHey taking no parameter and returning a Controller::AlbumOps (search for "C++ most vexing parse").)
Is there a way for functions to call each other i.e.
void menu()
{
some code here
play();
...
}
int play()
{
...
menu();
...
return 0;
}
Add the declaration of the second function at the top of your code file:
int play();
void menu()
{
// some code here
play();
// ...
}
int play()
{
// ...
menu();
// ...
return 0;
}
This is called a forward declaration, and it informs the compiler that an identifier will be declared later.
It is a way of denoting a function so that you can call it before you provide the complete definition.
Yes, but this is almost never what you want to do since careless use will break the stack.