strncpy_s using G++ compilers - c++

I originally programmed an assignment using Microsoft/visual c++ compilers, but my course requires me to run and compile on unix using G++
However, strncpy_s does not compile using g++, any workaround for my specific program?
This is code snippet that uses it:
void PhoneNumber::setName(const char name[])
{
strncpy_s(_name, name, MAX_NAME_LENGTH);
}

The *_s functions are Microsoft's attempt at being clever and "securing" the C runtime library's string functions. The functions even made it into C99's Appendix K. They are not implemented in Linux' glibc at the time of this writing. If you absolutely must (and I advise against it), just use the normal C library functions correctly (this means no magic numbers and proper buffer sizes everywhere), and yes, this is a pain in the bum.
This might or might not be usable within the context of your assignment, but it is really the only correct answer:
class PhoneNumber
{
private:
std::string name;
// ...
public:
void setName(std::string name);
//...
};
void PhoneNumber::setName(std::string name)
{
this->name = std::move(name); // 'this->' is optional, but clarifies without resorting to some clever renaming of the variables
}
Alternatively, drop the setter altogether:
struct PhoneNumber
{
std::string name;
// ...
};
and assign the member directly. But this style of coding, although perfectly sane, might get you yelled at by your teacher.
Don't use C char arrays in C++. You'll shoot yourself in the foot for no good reason. It also gets rid of the magic number in your code, which is always a plus.
Tiny C++11 and later template wankery. The ideal solution of implementing the setter is using templates, so that a potential costly double-move can be prevented if the setter is called like setName(std::move(some_string)):
template<typename T>
void setName(T&& name) { this->name = std::forward<T>(name); }
This will allow anything that is assignable/moveable to a std::string to be accepted, which is actually quite nice all in all. As an added benefit, you get the best possible code path selected for you automagically. Of course for your assignment this will be huge overkill, but if you take the time to learn about these concepts you might just teach the teacher something. Again, prefer a public member to this template ... wankery, because that is what this is.

You should not be using strncpy or its _s version, it may be quite surprising in its behaviour.
Use strlcpy instead, see strlcpy and strlcat - consistent, safe, string copy and concatenation.

Related

Why would you declare a std::string using it's constructor?

Most people when declaring strings in C++, or most other languages, do it like so:
std::string example = "example";
However I've seen some code samples where it is done like this:
std::string example("example");
To me it seems like it needlessly obfuscates the code, particularly if there is a using std::string statement hiding somewhere above the declaration in the code making it look like
string example("example");
To some who may be new to the codebase or are coming from other languages it almost looks like it could be a method or a function.
Is there any practical or performance based reason for using the constructor instead of the assignment operator or does it come down to just personal preference?
The practical reason for the second form is that it reflects what actually happens. Your two examples actually - despite their syntactic differences - do exactly the same thing.
They are both calling a constructor which accepts a const char * to initialise example with the literal "example".
The main difference is the way they are interpreted at times. I've lost count of the number of times I've seen people insist that
std::string example = "example";
does an assignment that calls std::strings operator=() function - except that it doesn't.
People who get tired of fielding such claims (and prefer that someone looking at the code can understand what it actually does, wherever possible) therefore sometimes prefer the second form;
std::string example("example");
Sometimes you don't have a choice. Many constructors are explicit (even some of std::string's constructors) and you can't call it with the type object = value syntax, and for consistency type object(value) would be much better. Being explicit prevents mistakes on things like std::vector<char> v = 'c'; or MyString s = 'v'; that doesn't work as one expects
But C++11 introduced the new {} initializer syntax and most modern coding conventions strongly prefer it, so you should use this instead
std::string example{ "example" }; // good
auto example{ "example"s }; // better
Even ISO CPP's Core C++ Guidelines suggests that in ES.23: Prefer the {} initializer syntax
This has the advantage of preventing narrowing, and it works even for in-class initialization
struct foo {
// OK
std::string example1 = { "example" };
std::string example2{ "example" };
std::string example3 = "example";
// Doesn't work
std::string example4("example");
};
To some who may be new to the codebase or are coming from other languages it almost looks like it could be a method or a function.
That's the well-known most vexing parse issue in C++. Both std::string example(std::string(someIdentifier)) and string example(string(someIdentifier)) can represent either a function declaration or a variable definition with initialization. If you learn C++ you have to learn the syntax
In fact most vexing parse is one of the reasons of the introduction to the new {} initialization form
See also
What are the advantages of list initialization (using curly braces)?
Why uniform initialization (initialization with braces) is recommended?
When to use the brace-enclosed initializer?

"Redirect" class member functions?

Basically I found myself today writing lots of code like below:
#define VAL_1 0
#define VAL_2 1
class A {
public:
void memberA();
void memberB();
...
void write(uin32_t address);
}
void
A::
memberA() {
this->write(VAL_1);
}
void
A::
memberB() {
this->write(VAL_2);
}
...
So basically, I have "pretty" names memberA, memberB for some task that really only does call the same function write with a different argument. The values VAL_0 and VAL_1 are not necessarily known to code using my class. Neither is the implementation detail behind memberA or memberB, although writemight be going public at some point.
Basically, now I'm repeating the same line of code this->write(...) over and over again. I'm looking for a solution that bypasses this step and calls the respective write immediately. A kind of passing on of the function arguments somewhat like a C++ constructor from a base class, possibly with matching arguments:
#define VAL_1 0
#define VAL_2 1
class A {
public:
bool memberA() : write(VAL_1);
bool memberB() : write(VAL_2);
...
bool write(uin32_t address);
}
I'm wondering whether there might be something in Boost.Bind or some clever template-coding that lets me achieve this kind or thing?
Thanks,
FRob
If you make your memberX functions inline in the class definition, and if you avoid the redundant this reference, then you don't have too much extra to write:
Your desired (incorrect) syntax:
bool memberA() : write(VAL_1);
The actual (correct) syntax:
bool memberA() { return write(VAL_1); }
If you want to minimize your repetitive code, you could use the pre-processor:
#define F(l, n) bool l() { return write(n); }
F(memberA, VAL_1)
F(memberB, VAL_2)
#undef F
Further, you could use the preprocessor token-pasting operator ##:
#define F(l, n) bool member##l() { return write(VAL_##n); }
F(A, 1)
F(B, 2)
#undef F
Without fully understanding what you are after (I got confused about the last part involving constructors), I think you might be trying a little too hard to make the syntax easier on your clients.
... how about simply:
class A {
public:
enum Value {val1, val2, val3, val4, etc};
bool write(Value val);
};
It's good that you are trying to establish an easier syntax, but you also have to avoid the danger of monolithism. Monolithic classes are something that I strongly believe is one of the most common mistakes in object-oriented design. Sutter goes into this in detail in C++ Coding Standards and on gotw: http://www.gotw.ca/gotw/084.htm.
If you have a class with 100 member functions, you probably have about 80 too many.
^ Think about this statement for a while. When you have so many functions, your classes tend to become increasingly hard to manage. It also invites other developers to just keep adding more and more to your class so that its design is never finalized. The result is the never-ending class that just grows and grows with each development cycle with no end in sight. That can easily become a source of bugs, inefficiencies, constant public interface revisions, unit test breakages, and it can go against the general reuse and flexibility of your class. When you have a separate function per value you can pass to another function, you're dangerously treading into that territory.
Trying too hard to avoid syntactical redundancy is usually a mistake. Unfortunately C++ just requires more lengthy syntax in some cases (getting much better with C++11). What you should try to optimize away is logical redundancy. Here calling write method with various values involves no logical redundancy, and the syntactical overhead is barely more than calling different functions for each value you can possibly pass to write.
If these functions do nothing more than simplify the syntax of passing various values, you have to come to the realization that you are also bloating the class's public interface with a whole lot more functions that, if you are in a production environment, you will likely have to document and teach individually. Strive for doing more with less and I think you'll be much better off.
Try to keep this aspect of monolithism in mind as a priority. You might even go so far as to hoist the named constants out of the class definition as non-members, like so:
class A {
bool write(uint32_t address);
};
// elsewhere
static const uint32_t address_val1 = ...;
static const uint32_t address_val2 = ...;
static const uint32_t address_val3 = ...;
There's actually nothing wrong with this design and, in fact, it has more desirable engineering characteristics than the one where you have more class members as it's completely decoupled from your class, making the maintenance of that class easier, its interface simpler to teach and document, and more likely to meet a state of reasonable completion.

Find uninitialized variables in C&C++

I really mean C and C++. This project is using a lib in C which is calling my functions in C++. However the functions are in extern "C" because the lib expects it.
Anyways, in these functions I do new Blah. When a specific function is called (end_tree) i expect all my variables to be initialized. Using Visual Studios, GCC or any other compiler is there a way i can check? I just notice some bools are TRUE which shouldn't be... why, because it wasn't initialized. Is there some kind of _VS_CheckThisMemory(mytree) function or magic I can use?
Don't know it this is what you want but gcc has -Wmaybe-uninitialized and -Wuninitialized. There may be more on the warning options page.
Use valgrind (on linux)
./valgrind myprogram
Especially easy when myprogram was compiled with debug info (gcc -g), but not required. Valgrind will notify where memory is being used that was uninitialzed, and where it was allocated from. If it has debug info, valgrind will report exactly at which file:linenumber things happened. (it can even attach a debugger on the fly for you to insepct things)
It will also detect access beyond allocation boundaries and access after freeing. This is incredibly useful.
Here endeth the useful answer
Edit because it wasn't exactly clear why I was posting the following, as became clear from the comment, let me introduce the remainder of this answer:
When starting to use valgrind with existing codebases, it is almost inevitable that you'll get 'false' positives, i.e. reports that aren't really problems (yet). I include one example of what might trigger such a report, and how you'd typically fix those.
I'm just including this to raise awareness of how to tackle or recognize (semi-)false positives.
Another way of wording it (with reference to Matthieu's convincing reasoning in the comments) is to treat even the 'not-actually-killing' Valgrind warnings as critical: get them fixed, not forgotten.
It is possible that valgrind will report uninitialized access when it is not really a problem. Like, e.g.
char buf[1024];
strcpy(buf, "hello");
char clone[1024];
memcpy(clone, buf, 1024);
You should fix that by doing something smarter like
memcpy(clone, buf, strlen(buf));
To make sure there are no uninitialzed 'parts' in buf (or at least not in the area accessed)
Use a self-initializing class to cover those annoying primitives.
template<typename T> class always_initialized {
T t;
public:
always_initialized()
: t(T()) {}
always_initialized(const T& ref) {
: t(ref) {}
operator T&() { return t; }
operator const T&() const { return t; }
T& operator=(const T& ref) { return t = ref; }
};
In response to the code linked in the comment, RAIIIA (Resource Acquisition is Initialization In Action (R))
class OtherClass;
class MyClass : public SomeBase {
public:
// note I got rid of your default constructor, which leaves values unitialized
MyClass(Var* name, OtherClass* loop)
: m_name(name), m_loop(loop) // this right here
{ }
virtual ~MyClass(); // no implementation needed here
void save();
// made the members protected, other classes have no business accessing them directly
protected:
Var* m_name;
OtherClass* m_loop;
};
Your default constructor left the values unitialized, and goes against RAII in its pure form. It's OK to do that, but as you're having problems with uninitialized variables, I would recomment removing default constructors.
EDIT: storing unknown pointers as class members without newing and deleteing them in the class constructor/destructor isn't really RAII, but I hope you do that somewhere.
I solved this by using a solution with templates to act like properties. I used Property like features in C++? but there are other examples for other things like passing in a get/setter.
Essentially generated most of this code bc i was able to and i kept track if a variable was set or not through the property. At the end i just check members and had asserts to tell me if i set a variable or not. I also assert when i 'get' just in case.

Does it ever make sense to make a fundamental (non-pointer) parameter const?

I recently had an exchange with another C++ developer about the following use of const:
void Foo(const int bar);
He felt that using const in this way was good practice.
I argued that it does nothing for the caller of the function (since a copy of the argument was going to be passed, there is no additional guarantee of safety with regard to overwrite). In addition, doing this prevents the implementer of Foo from modifying their private copy of the argument. So, it both mandates and advertises an implementation detail.
Not the end of the world, but certainly not something to be recommended as good practice.
I'm curious as to what others think on this issue.
Edit:
OK, I didn't realize that const-ness of the arguments didn't factor into the signature of the function. So, it is possible to mark the arguments as const in the implementation (.cpp), and not in the header (.h) - and the compiler is fine with that. That being the case, I guess the policy should be the same for making local variables const.
One could make the argument that having different looking signatures in the header and source file would confuse others (as it would have confused me). While I try to follow the Principle of Least Astonishment with whatever I write, I guess it's reasonable to expect developers to recognize this as legal and useful.
Remember the if(NULL == p) pattern ?
There are a lot of people who will tell a "you must write code like this":
if(NULL == myPointer) { /* etc. */ }
instead of
if(myPointer == NULL) { /* etc. */ }
The rationale is that the first version will protect the coder from code typos like replacing "==" with "=" (because it is forbidden to assign a value to a constant value).
The following can then be considered an extension of this limited if(NULL == p) pattern:
Why const-ing params can be useful for the coder
No matter the type, "const" is a qualifier that I add to say to the compiler that "I don't expect the value to change, so send me a compiler error message should I lie".
For example, this kind of code will show when the compiler can help me:
void bar_const(const int & param) ;
void bar_non_const(int & param) ;
void foo(const int param)
{
const int value = getValue() ;
if(param == 25) { /* Etc. */ } // Ok
if(value == 25) { /* Etc. */ } // Ok
if(param = 25) { /* Etc. */ } // COMPILE ERROR
if(value = 25) { /* Etc. */ } // COMPILE ERROR
bar_const(param) ; // Ok
bar_const(value) ; // Ok
bar_non_const(param) ; // COMPILE ERROR
bar_non_const(value) ; // COMPILE ERROR
// Here, I expect to continue to use "param" and "value" with
// their original values, so having some random code or error
// change it would be a runtime error...
}
In those cases, which can happen either by code typo or some mistake in function call, will be caught by the compiler, which is a good thing.
Why it is not important for the user
It happens that:
void foo(const int param) ;
and:
void foo(int param) ;
have the same signature.
This is a good thing, because, if the function implementer decides a parameter is considered const inside the function, the user should not, and does not need to know it.
This explains why my functions declarations to the users omit the const:
void bar(int param, const char * p) ;
to keep the declaration as clear as possible, while my function definition adds it as much as possible:
void bar(const int param, const char * const p)
{
// etc.
}
to make my code as robust as possible.
Why in the real world, it could break
I was bitten by my pattern, though.
On some broken compiler that will remain anonymous (whose name starts with "Sol" and ends with "aris CC"), the two signatures above can be considered as different (depending on context), and thus, the runtime link will perhaps fail.
As the project was compiled on a Unix platforms too (Linux and Solaris), on those platforms, undefined symbols were left to be resolved at execution, which provoked a runtime error in the middle of the execution of the process.
So, because I had to support the said compiler, I ended polluting even my headers with consted prototypes.
But I still nevertheless consider this pattern of adding const in the function definition a good one.
Note: Sun Microsystems even had the balls to hide their broken mangling with an "it is evil pattern anyway so you should not use it" declaration. see http://docs.oracle.com/cd/E19059-01/stud.9/817-6698/Ch1.Intro.html#71468
One last note
It must be noted that Bjarne Stroustrup seems to be have been opposed to considering void foo(int) the same prototype as void foo(const int):
Not every feature accepted is in my opinion an improvement, though. For example, [...] the rule that void f(T) and void f(const T) denote the same function (proposed by Tom
Plum for C compatibility reasons) [have] the dubious distinction of having been voted into C++ “over my dead body”.
Source: Bjarne Stroustrup
Evolving a language in and for the real world: C++ 1991-2006, 5. Language Features: 1991-1998, p21.
http://www.stroustrup.com/hopl-almost-final.pdf
This is amusing to consider Herb Sutter offers the opposite viewpoint:
Guideline: Avoid const pass-by-value parameters in function declarations. Still make the parameter const in the same function's definition if it won't be modified.
Source: Herb Sutter
Exceptional C++, Item 43: Const-Correctness, p177-178.
This has been discussed many times, and mostly people end up having to agree to disagree. Personally, I agree that it's pointless, and the standard implicitly agrees -- a top-level const (or volatile) qualifier doesn't form part of the function's signature. In my opinion, wanting to use a top-level qualifier like this indicates (strongly) that the person may pay lip-service to separating interface from implementation, but doesn't really understand the distinction.
One other minor detail: it does apply to references just as well as pointers though...
It makes the compiler do part of the work of catching your bugs. If you shouldn't be modifying it, make it const, and if you forget, the compiler will yell at you.
If bar is marked const as above, then the person reading the code, knowing what was passed in, knows at all time exactly what bar contains. There's no need to look at any code beforehand to see if bar got changed at any point along the way. This makes reasoning about the code simpler and thus reduces the opportunity for bugs to creep in.
I vote "good practice" myself. Of course I'm also pretty much a convert to functional languages these days so....
Addressing the comment below, consider this source file:
// test.c++
bool testSomething()
{
return true;
}
int test1(int a)
{
if (testSomething())
{
a += 5;
}
return a;
}
int test2(const int a)
{
if (testSomething())
{
a += 5;
}
return a;
}
In test1 there is no way for me to know what the value being returned will be without reading the (potentially sizable and/or convoluted) body of the function and without tracking down the (potentially distant, sizable, convoluted and/or source-unavailable) body of the function testSomething. Further, the alteration of a may be the result of a horrific typo.
That same typo in test2 results in this at compile-time:
$ g++ test.c++
test.c++: In function ‘int test2(int)’:
test.c++:21: error: assignment of read-only parameter ‘a’
If it was a typo, it's been caught for me. If it isn't a typo, the following is a better choice of coding, IMO:
int test2(const int a)
{
int b = a;
if (testSomething())
{
b += 5;
}
return b;
}
Even a half-baked optimizer will generate identical code as in the test1 case, but you're signalling that care and attention will have to be paid.
Writing code for readability involves a whole lot more than just picking snazzy names.
I tend to be a bit of a const fiend so I personally like it. Mostly it's useful to point out to the reader of the code that the variable passed in wont be modified; in the same way that I try to mark every other variable that I create within a function body as const if it's not modified.
I also tend to keep the function signatures matching even though there's not much point in it. Partly it's because it doesn't do any harm and partly it's because Doxygen used to get a bit confused if the signatures were different.

Excessive use of `this` in C++ [duplicate]

This question already has answers here:
When should I make explicit use of the `this` pointer?
(12 answers)
Closed 6 years ago.
I'm dealing with a large code base that uses the following construct throughout
class MyClass
{
public:
void f(int x);
private:
int x;
};
void MyClass::f(int x)
{
'
'
this->x = x;
'
'
}
Personally, I'd always used and hence prefer the form
class MyClass
{
public:
void f(int x);
private:
int _x;
};
void MyClass::f(int x)
{
'
'
_x = x;
'
'
}
The reasons I prefer the latter are that it is more succinct (less code = fewer potential bugs), and that I don't like having multiple variables of the same name in scope at the same time where I can avoid it. That said, I am seeing the former usage more and more often these days. Is there any upside to second approach that I am unaware of? (e.g. effect on compile time, use with templated code, etc...) Are the advantages of either approach significant enough merit a refactor to the other? Reason I ask, that while I don't like the second approach present in the code, the amount of effort and associated risk of introducing further bugs don't quite merit a refactor.
Your version is a bit cleaner, but while you're at it, I would:
Avoid leading underscore: _x is ok until somebody chooses _MyField which is a reserved name. An initial underscore followed by a capital letter is not allowed as a variable name. See: What are the rules about using an underscore in a C++ identifier?
Make the attribute private or protected: the change is safe if it compiles, and you'll ensure your setter will be used.
The this-> story has a use, for example in templated code to make the field name dependent on your type (can solve some lookup issues).
A small example of name resolutions which are fixed by using an explicit this-> (tested with g++ 3.4.3):
#include <iostream>
#include <ostream>
class A
{
public:
int g_;
A() : g_(1) {}
const char* f() { return __FUNCTION__; }
};
const char* f() { return __FUNCTION__; }
int g_ = -1;
template < typename Base >
struct Derived : public Base
{
void print_conflicts()
{
std::cout << f() << std::endl; // Calls ::f()
std::cout << this->f() << std::endl; // Calls A::f()
std::cout << g_ << std::endl; // Prints global g_
std::cout << this->g_ << std::endl; // Prints A::g_
}
};
int main(int argc, char* argv[])
{
Derived< A >().print_conflicts();
return EXIT_SUCCESS;
}
Field naming has nothing to do with a codesmell. As Neil said, field visibility is the only codesmell here.
There are various articles regarding naming conventions in C++:
naming convention for public and private variable?
Private method naming convention
c++ namespace usage and naming rules
etc.
This usage of 'this' is encouraged by Microsoft C# coding standards. It gives a good code clarity, and is intended to be a standard over the usage of m_ or _ or anything else in member variables.
Honestly, I really dislike underscore in names anyway, I used to prefix all my members by a single 'm'.
A lot of people use this because in their IDE it will make a list of identifiers of the current class pop up.
I know I do in BCB.
I think the example you provide with the naming conflict is an exception. In Delphi though, style guidelines use a prefix (usually "a") for parameters to avoid exactly this.
My personal feeling is that fighting an existing coding convention is something you should not do. As Sutter/Alexandrescu puts it in their book 'C++ coding conventions': don't sweat the small stuff. Anyone is able to read the one or the other, whether there is a leading 'this->' or '_' or whatever.
However, consistency in naming conventions is something you typically do want, so sticking to one convention at some scope (at least file scope, ideally the entire code base, of course) is considered good practice. You mentioned that this style is used throughout a larger code base, so I think retrofitting another convention would be rather a bad idea.
If you, after all, find there is a good reason for changing it, don't do it manually. In the best case, your IDE supports these kind of 'refactorings'. Otherwise, write a script for changing it. Search & replace should be the last option. In any case, you should have a backup (source control) and some kind of automated test facility. Otherwise you won't have fun with it.
Using 'this' in this manner is IMO not a code smell, but is simply a personal preference. It is therefore not as important as consistency with the rest of the code in the system. If this code is inconsistent you could change it to match the other code. If by changing it you will introduce inconsistency with the majority of the rest of the code, that is very bad and I would leave it alone.
You don't want to ever get into a position of playing code tennis where somebody changes something purely to make it look "nice" only for somebody else to come along later with different tastes who then changes it back.
I always use the m_ naming convention. Although I dislike "Hungarian notation" in general, I find it very useful to see very clearly if I'm working with class member data. Also, I found using 2 identical variable names in the same scope too error prone.
I agree. I don't like that naming convention - I prefer one where there is an obvious distinction between member variables and local variables. What happens if you leave off the this?
class MyClass{
public:
int x;
void f(int xval);
};
//
void MyClass::f(int xval){
x = xval;
}
In my opinion this tends to add clutter to the code, so I tend to use different variable names (depending on the convention, it might be an underscore, m_, whatever).
class MyClass
{
public:
int m_x;
void f(int p_x);
};
void MyClass::f(int p_x)
{
m_x = p_x;
}
...is my preferred way using scope prefixes. m_ for member, p_ for parameter (some use a_ for argument instead), g_ for global and sometimes l_ for local if it helps readability.
If you have two variables that deserve the same name then this can help a lot and avoids having to make up some random variation on its meaning just to avoid redefinition. Or even worse, the dreaded 'x2, x3, x4, etc'...
It's more normal in C++ for members to be initialised on construction using initialiser.
To do that, you have to use a different name to the name of the member variable.
So even though I'd use Foo(int x) { this.x = x; } in Java, I wouldn't in C++.
The real smell might be the lack of use of initialisers and methods which do nothing other than mutating member variables, rather than the use of the this -> x itself.
Anyone know why it's universal practice in every C++ shop I've been in to use different names for constructor arguments to the member variables when using with initialisers? were there some C++ compilers which didn't support it?
I don't like using "this" because it's atavistic. If you're programming in good old C (remember C?), and you want to mimic some of the characteristics of OOP, you create a struct with several members (these are analogous to the properties of your object) and you create a set of functions which all take a pointer to that struct as their first argument (these are analogous to the methods of that object).
(I think this typedef syntax is correct but it's been a while...)
typedef struct _myclass
{
int _x;
} MyClass;
void f(MyClass this, int x)
{
this->_x = x;
}
In fact I believe older C++ compilers would actually compile your code to the above form and then just pass it to the C compiler. In other words -- C++ to some extent was just syntactic sugar. So I'm not sure why anyone would want to program in C++ and go back to explicitly using "this" in code -- maybe it's "syntactic Nutrisweet"
Today, most IDE editors color your variables to indicate class members of local variables. Thus, IMO, neither prefixes or 'this->' should be required for readability.
If you have a problem with naming conventions you can try to use something like the folowing.
class tea
{
public:
int cup;
int spoon;
tea(int cups, int spoons);
};
or
class tea
{
public:
int cup;
int spoon;
tea(int drink, int sugar);
};
I think you got the idea. It's basically naming the variables different but "same" in the logical sense. I hope it helps.