Well, I wrote a simple code to check the possibility of creating objects using 'new' operator. When I was trying to compile the code, the MS Visual Studio threw the error like this: " Error: Unable to open file C:\Users...\test1\Debug\main.obj. Error code = 0x80070002.Error: Could not find 'C:\Users...\test1\Debug\main.obj'. test1.exe was built with /DEBUG:FASTLINK which requires object files for debugging.
What is going on? Please help.
Code:
#include <iostream>
class czlowiek {
int wiek;
char plec;
czlowiek();
czlowiek(int Wiek, int Plec);
};
czlowiek::czlowiek(int Wiek, int Plec) {
wiek = Wiek;
plec = Plec;
}
int main()
{
czlowiek *first;
first = new czlowiek();
delete first;
std::cin.get();
return 0;
}
The code you posted will not link:
The constructor czlowiek() doesn't have an implementation.
Both constructors are private (in classes members and methods are private by default).
As warning, you are assigning a int to a char (plec).
Related
See code below
#include <iostream>
#include <string>
namespace stringhelper
{
std::string to_string(int n) { return "0"; } // ignore wrong implementation. simplified for example purpose
}
using stringhelper::to_string;
class TestClass
{
public:
std::string to_string() const { return "TestClass:" + to_string(m_value); }
private:
int m_value;
};
int main()
{
TestClass tc;
std::cout << tc.to_string();
}
If TestClass does not implement function to_string(), within TestClass, it is able to resolve to_string(m_value) to stringhelper::to_string(int). However, the moment TestClass implements function to_string(), the compiler is unable to resolve to_string(int) to stringhelper::to_string.
Rather, it insists/resolves the function to TestClass::to_string and gave an error that the function TestClass::to_string does not take in 1 arguments.
Why is this so?
Environment:
Visual Studio 2008 Professional Edition 9.0.21022.8 RTM
Configuration: Win32
Windows 8
This behavior is not limited to Visual Studio 2008. If tested in modern Clang implementations you will see the same behaviour. As you may know, functions in derived classes which don't override functions in base classes but which have the same name will hide other functions of the same name in the base class.
The "problem" here is that you, by using the using statement introduces a function named to_string into a scope that is essentially a victim of the exact same thing as what happens in the above example, when looking at it from inside your class.
If the standard had you call member functions with this->foo() this would probably not have been an issue. But since function calls within a class are presumed to be part of the class and only if not found looked for in other scopes this becomes an issue.
Since you have an implementation in your class, that has priority and will be used. Since you want a version that takes an int as an argument, an overloaded version of your member function will be looked for and since it does not exist you get the error you see.
This is part of why using namespace can often introduce errors that might be unintuitive to understand. If you want to make sure you use the stringhelper::to_string implementation while you are in a class with a function that has the same name you have to be explicit.
This would work fine for instance, even if you keep your using statement.
#include <iostream>
#include <string>
namespace stringhelper
{
std::string to_string(int n) { return "0"; } // ignore wrong implementation. simplified for example purpose
}
using stringhelper::to_string;
class TestClass
{
public:
std::string to_string() const { return "TestClass:" + stringhelper::to_string(m_value); }
private:
int m_value;
};
int main()
{
TestClass tc;
std::cout << tc.to_string();
}
I used CLion as an IDE, it reports an error in IDE as
field z must be initialized
It can compile and run. But if I change const int z{3}; to const int z=3;, no error will be reported in IDE. My question is whether it is indeed an error of my codes or it is just a bug in the IDE? Any difference between these two initialization approaches? Did your IDE report this error?
#include <iostream>
using namespace std;
class Test
{
private:
const int x = 3;
int y;
const int z{3};
public:
Test(int);
int gety(){
return y;
}
};
Test::Test(int a){
y=x+4;
}
int main()
{
Test test(5);
std::cout << test.gety() << std::endl;
return 0;
}
whether it is indeed an error of my codes
There is no error in the code, it is OK.
or it is just a bug in the IDE?
It is a bug in whatever generates the error message. The IDE is high on my list of suspects but it could be another tool whose message the IDE relays.
Any difference between these two initialization approaches?
In this context (default member initializer) both syntaxes are semantically equivalent. There is no difference.
I am trying to build my project on both linux and windows. The project is already working on windows but I am facing a very weird error on GCC. Consider the following code:
Class Base {
private:
MessageInfo *createMsg();
}
Class MessageInfo {
private:
class Message{
...
}
public:
Message *messages[MAX_NO_MESSAGES];
...
}
MessageInfo *Base::createMsg(){
...
MessageInfo *newMsg = new MessageInfo;
newMsg->messages[i] = new MessageInfo::Message();
...
}
Now the problem is that in Visual Studio every thing compiles but in GCC I get the following error:
*Error: Class MessageInfo::Message is private
I am really surprised that the code actually compiles in Visual Studio but not in GCC. Any Suggestions???
EDIT:
I think I have to ask my question in a better way. My question is how is that even possible to compile such code in VS 2005??? I tried my code in VS2013 and it gave me the same error as GCC. So I am not arguing that the code is correct!
This does not compile in Visual Studio 2013:
class MessageInfo {
class Message { };
public:
Message *messages[256];
};
class Base {
MessageInfo *createMsg();
};
MessageInfo *Base::createMsg() {
MessageInfo *newMsg = new MessageInfo;
newMsg->messages[0] = new MessageInfo::Message(); // won't compile
}
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
The error, as you would expect, is:
error C2248: 'MessageInfo::Message' : cannot access private class declared in class 'MessageInfo'
Compilers are so different and I'm not really sure why VS would allow that to compile, any compiler I've used would have thrown a compile error.
What you're doing though is a bad way to think of a class. If you have the
class Message {...};
private in MessageInfo, then you shouldn't be able to access it anywhere outside of the class. We would only want Message to be available inside of the MessageInfo class and nowhere else. So you shouldn't return a Message* as you do in MessageInfo and you won't be able to access the Message() constructor as you do in main. Programming this way isn't allowed because otherwise it would completely goes against the purpose of encapsulation. If you really do want Message to be available to anyone, then make it public, but usually the inner workings of a class are hidden away from the user good reason: they shouldn't need to worry about it.
As suggested by egrunin I used the code that he suggested in his comment. Apparently you cannot compile that code in Visual Studio 2013 but I successfully compiled it on my machine using Visual Studio 2005. Here is the complete code that
used:
// Test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
class MessageInfo {
class Message { };
public:
Message *messages[256];
};
class Base {
MessageInfo *createMsg();
};
MessageInfo *Base::createMsg() {
MessageInfo *newMsg = new MessageInfo;
newMsg->messages[0] = new MessageInfo::Message(); // won't compile
return newMsg;
}
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
Am I doing some thing wrong here???
P.S:
I tried the code on Visual Studio 2010 and I got the cannot access private class declared in class 'MessageInfo' error!! Can anyone compile this code on Visual Studio 2005 so that I know what is wrong with VS 2005????
Here is the sample code that I ran on Visual Studio 2010:
#include <iostream>
int main()
{
int **p(NULL);
}
I get this error: error C2059: syntax error : 'constant'
But if I change int **p(NULL); to int **p = NULL; the above code compiles fine.
Checked this on GCC(Version:4.4.2) and both work fine. What am I missing here?
VC++ compiler seems confused about initializations of pointer to pointer ...
This works for example
int (**p)(NULL);
These don't
int *i;
int **p(&i);
int **o(NULL);
This works though
int (**p)(&i);
typedef int* intp;
intp *o(NULL);
etc... the pattern is initialization fails whenever two ** are present! I'd guess a bug! Someone from MSVC team might be able to confirm
That is either a bug in the compiler itself, or possibly you've done something and asked something else.
MSVC10 support few features from C++11, such as the following:
int **p1 = nullptr;
int **p2{}; //initialized to nullptr!
You can try any of these. Both are fine.
Looks like, defect with Visual studio, It works if i use c++ to compile # http://codepad.org/ and run the following code
int main()
{
int **p(NULL);
return 0;
}
Same works using g++ compiler as well.
You get a syntax error: apparently NULL is not defined. You should include cstdlib.
The following for creating a Global Object is resulting in compilation errors.
#include "stdafx.h"
#include <iostream>
using namespace System;
using namespace std;
#pragma hdrstop
class Tester;
void input();
class Tester
{
static int number = 5;
public:
Tester(){};
~Tester(){};
void setNumber(int newNumber)
{
number = newNumber;
}
int getNumber()
{
return number;
}
}
Tester testerObject;
void main(void)
{
cout << "Welcome!" << endl;
while(1)
{
input();
}
}
void input()
{
int newNumber = 0;
cout << "The current number is " << testerObject.getNumber();
cout << "Change number to: ";
cin >> newNumber;
cout << endl;
testerObject.setNumber(newNumber);
cout << "The number has been changed to " << testerObject.getNumber() << endl;
}
Here are the compile errors:
1>------ Build started: Project: test, Configuration: Debug Win32 ------
1>Compiling...
1>test.cpp
1>.\test.cpp(15) : error C2864: 'Tester::number' : only static const integral data members can be initialized within a class
1>.\test.cpp(33) : error C2146: syntax error : missing ';' before identifier 'testerObject'
1>.\test.cpp(33) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\test.cpp(49) : error C2039: 'getNumber' : is not a member of 'System::Int32'
1> c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::Int32'
1>.\test.cpp(55) : error C2039: 'setNumber' : is not a member of 'System::Int32'
1> c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::Int32'
1>.\test.cpp(57) : error C2039: 'getNumber' : is not a member of 'System::Int32'
1> c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::Int32'
1>Build log was saved at "file://c:\Users\Owner\Documents\Visual Studio 2008\Projects\test\test\Debug\BuildLog.htm"
1>test - 6 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
How do I create a Global Class
Object correctly like I've attempted
here.
And how do I fix that "only static
const integral data members can be
initialized within a class"
And basically how do I fix the rest
of the errors so I can get this to
compile?
I like declaring Global Class Objects at file scope (I like declaring all globals at file scope) because when I have to create separate source files and do "extern" and everything it becomes extremely complicated and never works for me. Although, I do want to figure out how to do that eventually... it seems every tutorial I look at won't compile though and unless it compiles I have no idea how to recreate it!
If I can just get this to compile...then I can successfully learn how to do this. So if someone could rewrite the above to where it literally copies & pastes into Visual C++ Express 2008 and works I will finally be able to figure out how to recreate it. I'm extremely excited on seeing the fix for this! It is just I can't get Global Objects to work right! Any other information on declaring Global Class Objects...or anything for that matter is welcome!
Just start addressing the errors one by one. A lot of the errors are just cascaded from the initial errors, so it looks like there are a lot of problems when there's only a couple. Just start from the top:
1>.\test.cpp(15) : error C2864: 'Tester::number' : only static const integral data members can be initialized within a class
You can't initialize a member in the class definition unless it's static, const, and one of the integral types. Leave the "= 5" off of the declaration of number. Then you'll need to have a definition of Tester::number outside of the class definition, like so:
int Tester::number = 5;
Problem #2:
1>.\test.cpp(33) : error C2146: syntax error : missing ';' before identifier 'testerObject'
Almost exactly what it says (missing semi-colon errors can be a bit inexact in saying where the semicolon should be) - you need a semi-colon after the definition of the Tester class.
Fix those and your compilation problems go away.
The key thing is to try and take compiler errors one at a time from the top. If you get more than about 3 of them, you can probably just ignore everything after the 3rd or so because the initial error just cause the compile to into the weeds (and if they are real errors, they'll show up again in the next compile anyway).
Error C2864: either add a const modifier to your integer, or move the initialization outside the class (as in class Tester { static int number; }; int Tester::number = 5;). The latter seems more appropriate to your case.
Error C2146: you're missing a semicolon after the declaration of class Tester { ... }. It should be class Tester { ... };
The other errors are probably caused by the previous error. They should fix themselves automatically when it is fixed.
As a side note, I don't think you really want the static modifier on your member. It seems more appropriate for an instance field. You still can't initialize it in-place though (this isn't C#), you have to move the initialization to the constructor. For example:
class Tester {
int number;
static int staticNumber; // just to show you how to use a static field
public:
Tester() : number(5) {}
~Tester() {} // I suggest you remove the destructor unless you need it
int getNumber() { return number; }
void setNumber(int value) { number = value; }
static int getStaticNumber() { return staticNumber; }
static void setStaticNumber(int value) { staticNumber = value; }
};
// initialize static members *outside* the class
int Tester::staticNumber = 5;
According to this: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/cplr038.htm
Tester testerObject;
int Tester::number = 5;
I'm not positive, but I think the rest of the errors come from that one problem.
Fix that, and see how far it gets you.
the answers already here deal with why your code doesn't compile and how to correct that. however i am intrigued by your comments about "extern". it is very easy to use when you know how. you declare in one header the extern'ed variable. and then you initialise it in one file. any other file can refer to the variable by including the header. e.g.
header.h:
// ensure the file is only included once
#ifndef _HEADER_H
#define _HEADER_H
extern int foo;
#endif
// end file header.h
header.cpp
#include "header.h"
int foo = 1;
// end file header.cpp
main.cpp
#include "header.h"
#include <stdio.h>
int main(int argc, char** argv)
{
printf("%d", foo);
return 0;
}
// end file main.cpp
Whilst using static class members for global variables helps fit the oo design scheme, its more elaborate than necessary. if you don't have to follow oo strictly, just use extern, its easier and its less code.