C++: Calling function in main.cpp from another .cpp file

In summary: This behavior of uniform initialization syntax is a double-edged sword. It's nice that narrowing is disallowed, but sometimes you need to do some kind of conversion and you don't want to write a static_cast, so you just use the = initializer syntax and forget the {} syntax exists. But then you might write something likedouble myDouble = 0.1;and forget that this is narrowing. It is recommended to always use {} for initialization when possible, but I think a lot of people forget to do that.
  • #1
JonnyG
233
30
I am trying to call a function declared in a .hpp file and defined in the corresponding .cpp file, from my main.cpp file, but I keep getting an error. From what I have googled it seems as if I am doing this the right way, so I was hoping you guys could help out. Here's my code:

Chap.hpp:
#ifndef CHAP_HPP
#define CHAP_HPP

class Chap
{
public:

double absoluteVal (double n) ;
unsigned fact (unsigned n) ;
};

#endif // CHAP_HPP

Chap.cpp:
#include "Chap.hpp"double absoluteVal (double n) {
    return (n >= 0) ? n : -n;
}

unsigned fact (unsigned n) {
    unsigned product {1};
    for (unsigned i = 1; i <= n; ++i)
        product *= i;
    return product;
}

main.cpp:
#include <iostream>
#include "Chap.hpp"

using std::cout;
using std::cin;
using std::endl;

int main() {
    cout << "Enter a number: ";
    double n;
    cin >> n;
    cout << "The absolute value of " << n << " is " << absoluteVal(n) << endl;
    return 0;
}

The error that I'm getting is:

C:/Users/J/Desktop/CPP/CppPrimer/CppPrimer/main.cpp: In function 'int main()':
C:/Users/J/Desktop/CPP/CppPrimer/CppPrimer/main.cpp:19:56: error: 'absoluteVal' was not declared in this scope

For what it's worth I am using the CodeLite IDE and a mingw-w64 compiler. I'd appreciate any help. Hopefully it's just me making a silly mistake.
 
Technology news on Phys.org
  • #2
The functions absoluteVal and fact are declared in Chap.hpp as members of the class Chap.

Therefore when you define the functions in Chap.cpp, you need to name them as Chap::absoluteVal and Chap::fact.

Also, when you use the functions in main.cpp, you first need to declare an object of type Chap. Then you can call the functions as members of that object, for example:

C++:
    Chap myChap;
// ... your other stuff
    cout << "The absolute value of " << n << " is " << myChap.absoluteVal(n) << endl;

Disclaimer: I have not actually tried to compile and run your code with these corrections.

I'm curious about why you want to write a class that has member functions but no member data.
 
  • Like
Likes sysprog
  • #3
This works. Thanks.

jtbell said:
I'm curious about why you want to write a class that has member functions but no member data.

I am going through C++ Primer. We are going over functions, so I write those two. I was then asked to create a header file with the function declarations in there. But then that got me thinking that I would like to remove my two functions (absoluteVal and fact) from my main.cpp file and put them in a .cpp file that corresponds to the header file I created. We haven't gone over classes in any detail yet. If I wanted to write a function (not a method - I am purposefully making this distinction), is the only way to include it in my main.cpp file? I feel like I may be asking a question for whose answer I may not be ready for yet.

EDIT: I just looked at the table of contents and in the next chapter we are going to cover classes and there is a section titled "defining nonmember class-related functions". I'm guessing that section will have my answer.
 
  • #4
If you want to have separate header and implementation files for plain old functions, then toss out your class Chap from Chap.hpp and replace it with just the prototypes of the two functions:

C++:
#ifndef CHAP_HPP
#define CHAP_HPP

double absoluteVal (double n) ;
unsigned fact (unsigned n) ;

#endif // CHAP_HPP

Then you should be able to use the original versions of main.cpp and Chap.cpp.
 
  • Like
Likes sysprog and JonnyG
  • #5
jtbell said:
Disclaimer: I have not actually tried to compile and run your code with these corrections.
That reminded me of this great line from Prof. Don Knuth (creator of ##\TeX##): Beware of bugs in the above code; I have only proved it correct, not tried it.
 
  • #6
Haha, yeah, I was going out on a limb because because it's past my bedtime and I wanted to get to sleep.

But now that I'm hooked on this, I went ahead and set up the files for my suggested version in post #4. The following line in Chap.cpp:

unsigned int product {1} ;

gave me the message error: expected ';' at end of declaration. Looking more closely I noticed the {1} which I've never used for initializing a scalar variable. I've always done it as something like

unsigned int product = 1 ;

I thought, maybe this is something from C++11 and newer? I told my g++ to use -std=c++11, and sure enough it worked. So now I've learned something. :cool:

It makes sense to allow initialization this way, because it's consistent with list-initialization of arrays, etc.
 
  • Like
Likes sysprog
  • #7
jtbell said:
Looking more closely I noticed the {1} which I've never used for initializing a scalar variable. I've always done it as something like

unsigned int product = 1 ;

I thought, maybe this is something from C++11 and newer? I told my g++ to use -std=c++11, and sure enough it worked. So now I've learned something. :cool:

It makes sense to allow initialization this way, because it's consistent with list-initialization of arrays, etc.
Yes, this is called uniform initialization syntax and was added in C++11. https://isocpp.org/wiki/faq/cpp11-language#uniform-init

It's 2020, and C++11 added many very good features that make many parts of the language easier and safer to use. I highly encourage you to always enable it (even better, C++14 or C++17). :smile:

In addition to providing a uniform syntax for initialization (as you noted, and as the name implies), it also has the advantage of disallowing implicit narrowing, so for example, lines 10 and 18 below are disallowed:
C++:
double myDouble {0.1};
uint32_t myUint32 {1};

// Error; assigning double-precision float to a single-precision float.
// Use
//    float myFloat {static_cast<float>(myDouble)};
// or
//    float myFloat = myDouble;
// instead.
float myFloat {myDouble};

// Error; assigning 32-bit integer to a 16-bit integer.
// Use
//    uint16_t myUint16 {static_cast<uint16_t>(myUint32)};
// or
//    uint16_t myUint16 = myUint32;
// instead.
uint16_t myUint16 {myUint32};
A couple of other notes: use of = with uniform initialization syntax is optional, so the following are equivalent:
C++:
int n {0};
int n = {0};
And empty braces provide default initialization, which calls the default no-argument constructor for class types, and zero-initialization for numerical types, so the following are equivalent:
C++:
int n {};
int n {0};
whereas of course this will result in an uninitialized variable, generally containing garbage:
C++:
int n;
 
Last edited:
  • Like
Likes sysprog

1. How do I call a function located in another .cpp file from my main.cpp file?

To call a function from another .cpp file, you first need to declare the function in the header file (.h) associated with the .cpp file. Then, include the header file in your main.cpp file and use the function as you would any other function declared in your main.cpp file.

2. Can I call a function from a different namespace in my main.cpp file?

Yes, you can call a function from a different namespace in your main.cpp file by using the scope resolution operator (::) to specify the namespace of the function. For example, if the function is in the namespace "myNamespace", you would call it as myNamespace::myFunction();

3. What is the benefit of calling a function in a separate .cpp file?

Calling a function in a separate .cpp file allows for better organization and modularity in your code. It also makes it easier to reuse the function in other parts of your program.

4. Can I call a function from a header file in my main.cpp file?

Yes, you can call a function from a header file in your main.cpp file as long as the header file contains the function declaration. If the function is defined in the header file, you may also need to include the corresponding .cpp file in your project to avoid linker errors.

5. Is it possible to call a function from a .cpp file without using a header file?

Technically, it is possible to call a function from a .cpp file without using a header file by declaring the function as "extern" in your main.cpp file. However, this is not considered a good practice and can lead to errors and difficulty in maintaining and debugging your code.

Similar threads

  • Programming and Computer Science
Replies
8
Views
1K
  • Programming and Computer Science
Replies
6
Views
922
  • Programming and Computer Science
2
Replies
39
Views
3K
  • Programming and Computer Science
Replies
8
Views
2K
  • Programming and Computer Science
Replies
12
Views
1K
  • Programming and Computer Science
Replies
22
Views
2K
  • Programming and Computer Science
Replies
33
Views
2K
  • Programming and Computer Science
Replies
5
Views
1K
  • Programming and Computer Science
Replies
4
Views
783
  • Programming and Computer Science
2
Replies
57
Views
3K
Back
Top