How can I declare a struct? - c++

I am currently learning C++ and trying to understand the usage of structs.
in C++. As far as I'm aware, if you want to define a function after the main() function, you have to declare it beforehand, like in this function (Please tell me if I'm wrong with it):
#include "stdafx.h"
#include <iostream>
#include <string>
void printText(std::string); // <-- DECLARATION
int main()
{
std::string text = "This text gets printed.";
printText(text);
}
void printText(std::string text)
{
std::cout << text << std::endl;
}
My question now is if there is a way to do the same with structs. I don't want having to always define a struct before the main() function, just because I prefer it like that. However, I get an error when I try doing it like that:
//THIS program DOESN'T work.
#include "stdafx.h"
#include <iostream>
#include <string>
struct Products {std::string}; // <-- MY declaration which DOESN'T work
int main()
{
Products products;
products.product = "Apple";
std::cout << products.product << std::endl;
}
struct Products
{
std::string product;
};
When I delete the decleration and instead define the struct before the main function, the program works so I assume I'm somehow wrong with the decleration:
//THIS program DOES work
#include "stdafx.h"
#include <iostream>
#include <string>
struct Products
{
std::string product;
};
int main()
{
Products products;
products.product = "Apple";
std::cout << products.product << std::endl;
}
Could someone tell me if there is some way to declare a struct like that? Bear with me if I have any major mistake in the code, I'm just a beginner.
Thanks in advance!

You can pre-declare (forward-declare) a class type in C++.
struct Products;
However, a class type declared in this way is incomplete. Incomplete types can only be used in a number of very limited ways. You will be able to declare pointers or references to such type, you will be able to mention it in non-defining function declarations etc., but you will not be able to define objects of such incomplete type or access their members.
If you want to define objects of class Products or access members of class Products, you have no other choice but to fully define the class before such use.
In your case you are defining an object of type Products in main as well as accessing members of class Products there. This means that you have to completely define Products before main.

In your particular case a forward declaration wont help, because a forward declaration only allows you to use pointers or references, as e.g. in
struct foo;
foo* bar(foo f*) { return f;}
struct foo { int x; }
However,
struct Products {std::string};
is not a declaration, but if you want an ill-formed declaration and definition.
The correct forward declaration would be:
struct Products;

Related

C++ use iostream inside class [duplicate]

This question already has an answer here:
Does not name a type
(1 answer)
Closed 2 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
I'm using iostream and map. When I try to set the functions, they throw an error.
My code:
#include "string"
#include "iostream"
#include "map"
using namespace std;
class myClass {
map<string, string> Map;
Map["Ziv"] = "Sion";
cout << Map["Ziv"];
};
My error:
error: 'Map' does not name a type
error: 'cout' does not name a type
Why I can't use iostream and cout?
Why I can't use iostream and cout?
Because a class cannot (directly) contain expression statements. It can contain only member declarations.
Expression statements can only be within functions. This would be correct for example:
class main {
map<string, string> Map;
void example_function() {
Map["Ziv"] = "Sion";
cout << Map["Ziv"];
}
};
you can't have a C++ progran without the main function so please create int main(){}. And change the double quotes in the #include directives to angle brackets like below:
#include <string>
#include <iostream>
#include <map>
using namespace std;
class myClass {
public:
int myFunc();
};
myClass :: int myFunc(){
map<string, string> Map;
Map["Ziv"] = "Sion";
cout << Map["Ziv"];
}
int main(){
myClass myclass;
myclass.myFunc();
return 0;
}
Please consider i am a beginner and forgive my mistakes if any.
In object oriented languages, like C++, you can't write expressions/statements in a class. You may want to use a function. Example:
#include<iostream>
using std::cout;
class Example {
public:
void sayHello() {
cout << "Hello!";
}
}
int main() {
new Example().sayHello(); // Prints Hello!
}
You have to enter the cout in a function, inside the class you can't execute functions, you just can describe them or variables / objects.
Class is an Entity which contains related data members and the operations to modify or access those data members. No expression can be executed within the class. It does not make an sense to do something that you can not access. Because the only way to access and modify something are operations.
Yes in case if you want to print something when the class object is created, you can do that in Constructor. May be this is what you want to do:
#include <map>
#include <iostream>
#include <string>
class myClass {
private:
std::map<std::string, std::string> Map;
public:
myClass(const std::string& key, const std::string& value){
Map[key] = value;
std::cout << value;
}
};
int main(){
myClass cls("Ziv", "Sion");
}

Can we get the object name using “this” pointer

I want to programmatically retrieve the identifier of a C++ class instance at runtime. I'm aware that C++ doesn't support reflection yet, but is there any alternative solution out there?
For instance, given the following example:
class Foo {
Foo() {
auto name = reflect::getIdentifierName(this);
std::cout << name << std::endl;
}
};
void main() {
Foo my_obj;
}
Executing this program should print out "my_obj".
I'm looking for any utility library that I could use to implement this basic reflection function.
I'm particularly wondering if libclang can be used to extract such information - if so, any hint for how to build the reflect function to do this.
Yes, but this is implementation defined. Proceed at your own risk.
Yunnosch's suggestion sounds much more reasonable without more context.
#include <iostream>
#include <typeinfo>
class Foo {
public:
Foo() {
const char * const name = typeid(this).name();
std::cout << name << std::endl;
}
};
int main()
{
Foo my_obj;
}

C++ Pass an object into another object?

I don't know if I've missed something, but I can't seem to figure out how to make this work, and couldn't find the answer online.
Lets say I have a two classes, Class A, and Class B. (stored in separate files)
Class A has a function setName() that sets a variable within a Class A object.
Class B has a function setOtherName() that sets the value of a Class A object's name.
So I set setOtherName() up like so:
void setOtherName(ClassA& cla)
{
*cla.setName("foobar");
}
then my main script looks like so:
Class A burger;
Class B fries;
fries.setOtherName(*burger);
this does not work in my orignal script, I get the following error:
error: no matching function for call to 'ClassB::setOtherName(ClassA*&)
Any help is aprreciated! ( sorry for any confusion )
Actual code:
main.cpp:
#include <iostream>
#include "quests.h"
#include "player.h"
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
quests GameQuests;
player Player;
GameQuests.quest1(Player);
Player.main();
return 0;
}
quests.cpp:
#include "quests.h"
#include "player.h"
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
void quests::quest1(player& charact){
cout << "By the way, what was your name?" << endl;
person1=4;
system("pause");
charact->setName();
}
The implementation of your setOtherName function should have the signature
void ClassB::setOtherName(ClassA& cla)
You need to specify that it is included in ClassB. Within your class definition of ClassB, make sure to include
void setOtherName(ClassA&);
Furthermore, since your variable burger is of type ClassA and not of type ClassA*, there is no need to dereference the variable upon passing it into the function. Call it like
fries.setOtherName(burger);
You have also incorrectly dereferenced the variable cla. That object is passed by reference, not pointer, so there is no need to dereference.
You have to read about pointers and reference mate.
This is how your function should look like
void setOtherName(ClassA& cla)
{
cla.setName("foobar");
}
There is no need to deference something that is not a pointer.
ClassA burger;
ClassB fries;
fries.setOtherName(burger);
again, you don't need to dereference burger since its not a pointer.
If burger was created like this:
ClassA* burger = new ClassA();
and the function
void setOtherName(ClassA& cla)
was taking a reference, you had to dereference burger
fries.setOtherName(*burger);
Why are you derefrencing burger? You told the compiler to expect class A by reference, not by pointer.
Try:
fries.setOtherName(burger);
Also, get rid of the asterisk on setOtherName.
void setOtherName(ClassA & cla)
{
cla.setName("foobar");
}
EDIT:
Wrote a sample program of what I think you are trying to do below.
#include <iostream>
#include <string>
class Burger
{
public:
Burger(){}
void setName(std::string name){ m_name = name; }
std::string getName(){ return m_name; }
private:
std::string m_name;
};
class Fries
{
public:
Fries(){}
void setOtherName(Burger & burger){ burger.setName("FryBurger"); }
private:
};
int main()
{
Burger A;
Fries B;
B.setOtherName(A);
std::cout << A.getName() << std::endl;
return 0;
}

How can I call the data type from the function of a class

I defined a class as well as member function. And now I would like to call the data type(x.dat) imported from outside.
How could I do that?
It would be something like this:
class abs{
private:
...
public:
...
void function(data){ //here i would like to use the external data x.dat
...
}
}
Yes, Keith is correct.
What you want is a static variable that maintains the same data across all objects of that type. You don't necessarily need a function to do this.
#include <iostream>
#include <string>
using namespace std;
class abs
{
private:
public:
static double data[3];
};
double abs::data[3]={}; //instantiate the variable
int main () {
abs::data[0]=5.0;
cout<<abs::data[0]; //outputs 5
}
Static variables are associated with the class definition, and not the instantiated objects of that type so as long as the program is active it will be stored in memory as part of the class.
Firstly, tremendous thanks to all of you, especially #Mir
I get it running now, although I don't know why does someone give me a negative!?
I would like to make a summary here, for myself, and future readers.
My question is this:
I have a stored data(double[1000]), which is a file of 'x.dat';
And I define a class 'abs' in the header file, as well as its member function 'function';
And 'function' would like to call data as a inputting parameter.
How to do these?
With the help of Mir, it's working now like this, hope it would help someone:
1.abs.h
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class abs
{
private:
public:
static double data[1000];
double function(double xa[]){
for(int i=0;i<1000;i++){
res += xa[i] * 2.0;
}
return res;
}
};
2.abs.cpp
#include "abs.h"
double abs::data[1000]={}; //instantiate the variable
3.main.cpp
#include "abs.h"
int main () {
abs a = abs();
for(int i = 0; i < 1000, i++){
ifstream fs("x.dat")
fs >> abs::data[i];
cout << abs::data[i]; //outputs all data
}
double Value = a.function(data);
cout<< Value<<endl;
}

Different code behavior in multiple files compared to collocated into single file

Code that I place in a single file behaves differently when separated into multiple files. I have a static field in a class (a std::vector) that I am modifying during global object instantiation which I analyze in main.
I suspect this is due to how objects are created in different scopes, but I thought this scenario would result in sharing the same object.
How can I separate this code and get the same result I see when the code is collocated?
UPDATE If I declare the static object in main.cpp the code works. Is this the only way? That feels messy, it's not where I want to declare it.
Here is the code.
utils.h
#pragma once
#include <vector>
#include <iostream>
class Collector
{
public:
static std::vector<int> Ints;
};
class Aggregator
{
public:
Aggregator(int i);
};
main.cpp
#include "utils.h"
// as noted in my updated question, if I declare Ints here, it works
// std::vector<int> Collector::Ints;
// but I want the freedom to declare this in any source
Aggregator inst(1);
int main()
{
std::cout << "size: " << Collector::Ints.size();
std::cin.get();
return 1;
}
utils.cpp
#include "utils.h"
std::vector<int> Collector::Ints;
Aggregator::Aggregator(int i)
{
Collector::Ints.push_back(i);
}
The output is size: 0
And all the same code in one file would look like this:
#include <vector>
#include <iostream>
class Collector
{
public:
static std::vector<int> Ints;
};
class Aggregator
{
public:
Aggregator(int i);
};
#include "utils.h"
std::vector<int> Collector::Ints;
Aggregator::Aggregator(int i)
{
Collector::Ints.push_back(i);
}
Aggregator inst(1);
int main()
{
std::cout << "size: " << Collector::Ints.size();
std::cin.get();
return 1;
}
And this outputs size: 1, as I desire.
One way to avoid this is to use a static function with a static variable in it.
So for example:
class Collector
{
public:
static std::vector<int> & GetInts(){ static std::vector<int> Ints; return Ints; }
};
This way you are guaranteed the static variable is initialized when you use it regardless of which cpp file you're using it in.
I should stress though that this is not a great idea as you'll have issues with threading. Is there a good reason to make this static?