Why the function bellow void i( ) is not called as in a 'Normal' function.
void i(){
cout << 10 << endl;
}
int main(){
class i {
int j;
};
i();//
return 0;
}
The normal behavior expected is to print 1O, but I did not getting anything, not a compiler warning nor the result.
The inner i is shadowing the outer one. You are calling the default constructor of class i which does nothing in this case.
The solution is to explicitly scope the call, as ::i();
Because it's trying to call "i" in the current scope:
You can call your function::i();
Related
I have been trying to include the declaration of the variable in the function itself but it doesn't work unless I include it in the main function. Why does this happen?
#include<iostream>
using namespace std;
function1(int x)
{
int x =1;
cout << x << endl;
return 0;
}
int main ()
{
function1( x);
return 0;
}` `
Welcome to the world of C++ coding! Looks like there's more than a few issues in the code here - let's break it down and see what we can find.
First and foremost, to answer your original question, your declaration of x (in function1) was made outside of the function you tried to use the variable in (in main). C++ can't normally see variables you declare in one function when it's running in another; that's by design, and is called scope.
To start, the code won't compile for a number of reasons, first and foremost the presence of stray backticks in your code at the very end. These need to be removed.
int main ()
{
function1( x);
return 0;
}` ` //<-- the ` ` will make the compiler angry
Now let's have a look at what's causing the error: x isn't yet declared. In C++, a variable has to be "declared" before it can be used. Since "x" hasn't been declared before its use in function( x);, the compiler kicks it back since it doesn't know what "x" means. Try this:
int x = 0;
function1( x);
We're not quite done yet, though. Once we make this change, the compiler will throw another error: In function 'int function1(int)': 8:5: error: declaration of 'int x' shadows a parameter. You've already included an int x in the definition of function1; by creating another int x inside function1, you've steamrolled your original x. Let's change that from a definition to an assignment.
function1(int x)
{
x =1;
cout << x << endl;
return 0;
}
Getting clsoer, but we've got one more error: 6:16: error: ISO C++ forbids declaration of 'function1' with no type [-fpermissive]. THis is telling you function1 needs to have a return type, which is a keyword in front of the function's name that tells the compiler what type of data it returns (void if it doesn't return any). Looks like you're using return 0; - why not return an int?
int function1(int x)
Now, at last, we've got code that compiles and runs.
#include<iostream>
using namespace std;
int function1(int x)
{
x =1;
cout << x << endl;
return 0;
}
int main ()
{
int x = 0;
function1( x);
return 0;
}
Try it here!
Good luck!
Why does this happen?
It happens because x is now undefined in the context where you're using it in main, and it's already defined (as a parameter) in the context where you're trying to define it in function1().
In the first case, you'll definitely get an error because x as used in main is completely undefined... the compiler is going to look at that function1(x) call and wonder what the heck it's supposed to supply for the x.
In the latter case, the compiler might let you redefine x, but it'll probably at least issue a warning. Also, if it's allowed, then your function1() will always print out 1 regardless of what you pass in for the x parameter because the newly declared x will be used instead of the value passed in the parameter.
The concept that you're missing is called scope. Every variable has a scope, which is essentially the realm in which it's known. The scope of a variable can be global, in which case it's available to the entire program, or limited to a single file, or it can be declared inside a function or block, in which case it's local to that block of code.
int x = 12; // x is available anywhere in the file and has initial value 12
void foo(int x)
{
cout << x << endl; // prints the value passed to foo by the caller
int x = 34; // this new x hides the parameter and is available
// anywhere inside this function, but not outside
cout << x << endl; // prints the new x, i.e. 34
{
cout << x << endl; // still prints 34
int x = 97; // hides the previous x, available only within
// this block or sub-blocks
cout << x << endl; // prints 97
} // x from the enclosed block goes out of scope
cout << x << endl; // prints 34, because we're back to the x at function scope
}
Understanding scope is very important because variable names are often duplicated, either on purpose or by accident, and you need to be able to tell where a given variable is in scope and therefore valid to use, and when it's not.
Why is it that I can access the data held within the object after assigning the pointer WHILE I'm within the scope of the assigning function, but cannot once I try to access the same value through the same pointer but outside of that function?
The pointer is a member function and is assigned within the function. Within the function, that works fine. But, when from within that function, I call ANOTHER function which uses the class scope, the pointer misbehaves, presenting garbage data. Why?
CODE:
#include <iostream>
class Object{
public:
Object( ) { std::cout << "Object constructor called." << std::endl; }
Object( const Object &in ) { i = in.i; std::cout << "Object copy constructor called." << std::endl; }
~Object( ) { std::cout << "Object destructor called." << std::endl; }
int i;
};
class ObjectManager{
public:
Object * retObject(){
Object *myObject = new Object;
myObject->i=55;
return myObject;
}
};
class LogicManager{
public:
LogicManager(){
myObjectManager = new ObjectManager;
}
~LogicManager(){
delete myObjectManager;
}
Object * retObject(){
return myObjectManager->retObject();
}
private:
ObjectManager *myObjectManager;
};
class Viewer{
public:
~Viewer( ) { if( myObject ) { delete myObject; } }
void ptrinObject( LogicManager * inLogic ){
myObject = inLogic->retObject();
std::cout << "Got path size of " << myObject->i << std::endl; //correct
std::cout << "Got path size of " << retObjectVal( ) << std::endl; //0?!?!?!?
}
int retObjectVal( ) { myObject->i; }
private:
Object *myObject;
};
int main(){
LogicManager myManager;
Viewer myViewer;
//myViewer.cpyinObject( &myManager );
myViewer.ptrinObject( &myManager );
return 0;
}
OUTPUT:
Object constructor called.
Got path size of 55
Got path size of 861280848
Object destructor called.
The problem is:
int retObjectVal( ) { myObject->i; }
There is no return statement in that function. You just have an expression with no side effect. As a result, we run into ยง6.6.3/2:
Flowing off the end of a function is equivalent to a return with no value; this results in undefined
behavior in a value-returning function.
It's undefined behavior what it returns, so it ends up returning some garbage. Just make it:
int retObjectVal() { return myObject->i; }
This is an easy mistake to make, which is why you should always try to compile with the highest warning settings possible. For instance, on gcc with no flags, I get no warnings. But with -Wall, I get:
warning: statement has no effect [-Wunused-value]
warning: no return statement in function returning non-void [-Wreturn-type]
First, you're not initializing Viewer::myObject so if you just do
void something() {
Viewer v;
}
You may end up trying to delete an invalid pointer.
myViewer.cpyinObject( &myManager );
myViewer.ptrinObject( &myManager );
Both functions create a new Object but neither checks to see if there's already one allocated (memory leak). Then later, they immediately ignore that new object created and instead assign yet another new Object allocated by ObjectManager (more memory leaks).
Finally, Viewer::retObjectVal does not actually specifically return a value and therefore you are receiving "junk off the end of the function".
I suggest you look at your compiler warnings as any sensible compiler will have warned you about the first and third issues I've mentioned.
In the Viewer class, you are missing a return statement:
int retObjectVal( ) { return myObject->i; }
should work.
What you have is a method where some of its branches fall off without returning a value. This leads to undefined behavior. You are simply evaluating "myObject->i;" as a statement.
Another issue you should probably address is that your Object pointers are not owned by anyone and not being deleted anywhere. Namely, you are deleting your ObjectManager but nowhere does it delete the underlying object itself. You should probably figure out an ownership model there, have someone keep track of these pointers, and delete them when appropriate.
Say I am writing a library that should provide some default computing (function), but enables the user to provide his own, at compile-time.
For instance, say the library provides a function that returns his argument times 3, but the user can provide his own function.
Consider the following program (to be seen as a MWE):
float myFunction( float v ) // the function the user needs
{
return v*2;
}
int main()
{
FuncWrapper f;
cout << "default: " << f(2) << endl; // should print "6"
f.AssignFunction( myFunction );
cout << "now is: " << f(2) << endl; // should print "4"
}
So I have build a functor FuncWrapper that wraps a std::function, as proposed also here:
struct FuncWrapper
{
std::function<float(float)> foo; // the function used
float def( float v ) // the default behaviour member function definition
{
return v*3;
}
float operator()( float v ) // call of function
{
return foo(v);
}
void AssignFunction( float (*uf)(float) ) { foo = uf; }
// constructor: initializes to default function
FuncWrapper() : foo(&FuncWrapper::def) {}
};
On my machine (gcc 4.6.3) with -std=c++0x, I get non human-readable error messages, as stated in this other answer. For conveniency, the code is runnable here. Seems to be gcc 4.8, and it doesn't like the constructor (among other errors...):
main.cpp: In constructor 'FuncWrapper::FuncWrapper()':
main.cpp:27:64: error: no matching function for call to 'std::function<float(float)>::function(float (FuncWrapper::*)(float))'
Why is this assignment illegal ? I have searched for this topic, maybe wrong keyword, but didn't find anything relevant.
Any clue? Or a simpler solution, maybe without std::function but with a function pointer?
In your example code, you try to assign your member function to a std::function with signature float(float). These two are not compatible, since the member function has a different calling convention: it requires a this argument.
Make your default function static to avoid this.
Within the same class I have
Executive::Executive(std::istream& fin){
std::ifstream dFin(argv[2]);
if(!dFin.is_open()){
std::cout <<"Could not open directives file.";
std::cout <<endl;
}
else{
std::string directive;
dFin >>directive;
int x;
dFin >>x;
if(directive=="print"){
}
and the function
void Executive::print(int i) const{
if(i>MAX_NUM_POLYNOMIALS){
std::cout <<"Sorry, " <<i <<" is not within the known polynomials.";
std::cout <<endl;
}
else{
pNom[i].print(std::cout);
std::cout << i <<'\n';
}
}
In the last bit of the first code, how do I call the print function from the second code? They're in the same class, and I don't want to confuse calling it with the print function being called from another class in the second part.
In short, there is no problem in calling the print method directly in here. There are some scenarios below though for consideration.
If you have a print method in a different class, you would simply use myAnotherClass.print(...).
If you need to call a print method explicitly from the base class, you can use the base class scope explicitly as presented in the example at the bottom, such as MyBaseClass::print(...)
It is a simple case when you cannot have any clash except if you have a print method in the global scope or a namespace being used.
If it is in the global area, you would call it with ::print(...), and if it is in a namespace, you could use myNamespace::print(...)
Try to avoid "this->" at all costs, and leave that as the last resort. If you had a 'print' argumnt in the method where you are calling print, that could be one case if you could not change the argument name otherwise for some reason.
Finally, after the theoretical lesson, here goes the practical example:
Executive::Executive(std::istream& fin){
std::ifstream dFin(argv[2]);
if(!dFin.is_open()){
std::cout <<"Could not open directives file.";
std::cout <<endl;
}
else{
std::string directive;
dFin >>directive;
int x;
dFin >>x;
if(directive=="print") {
print(x); // calling the method of the current class
MyBaseClass::print(x); // calling the method of the base class
myAnotherClass.print(x); // classing the method of a different class
::print(x); // calling print in the global scope
myNamespace::print(x); // calling the method in a dedicated namespace
}
If you want to be ABSOLUTELY sure you're calling your own function you can use the this keyword if it's not a static function or the class name if it is static.
this->print(...); or Executive::print(...);
You can just fully qualify the member function to call:
Executive::Executive(std::istream& fin)
{
// ...
if(directive == "print")
{
Executive::print(x);
}
// ...
}
I should note that if you're adding a non-static print method to another different class there is no chance of a name collision here. That's because to actually call that method from outside of its containing class you have to refer to some instance to call it with.
I am trying to understand how explicit constructor call in main works using the following code.
#include<iostream>
using namespace std;
class Dependency1
{
bool init;
public:
Dependency1() : init(true) {
std::cout << "Dependency1 construction"
<< std::endl;
}
void print() const {
std::cout << "Dependency1 init: "
<< init << std::endl;
}
};
class Dependency2 {
Dependency1 d1;
public:
Dependency2(const Dependency1& dep1): d1(dep1){
std::cout << "Dependency2 construction ";
print();
}
void print() const { d1.print(); }
};
void test( const Dependency1& dd1)
{
cout << " inside Test \n";
dd1.print();
}
int main()
{
test(Dependency1());
Dependency2 D1(Dependency1()); // this line does not work
return 0;
}
Function test is being called where constructor Dependency1() is used as a function call instead of Dependency1::Dependency1( ) and the code runs perfectly fine.
Now if I use similar concept to create an object D1 of Dependency2, it does not work.
Seems I am doing something wrong here based on wrong understanding.
Need to know how the Compiler resolves Dependency1() call in main even if scope resolution is not used and why it does not work when I use it as a parameter in constructor of Dependency2
Thanks,
Anand
test(Dependency1())
This calls a function test and passes a temporary object of class Dependency1. Because the formal parameter in the definition of test is a reference to const and because temporaries can be bound to const references your code works.
Dependency2 D1(Dependency1()); // this line does not work
This is called C++ most vexing parse. D1 is interpreted as a function returning Dependency2 and taking an argument a pointer to function returning Dependency1.
Try Dependency2 D1((Dependency1())); and see the change in output.
Note: Putting an extra pair of parenthesis would make the compiler treat (Dependency1()) as an expression.
Dependency1() creates a temporary object of type Dependency1, that is passed to function test.