Is the way i declared the Abstract-Class wrong/not common? [duplicate] - c++

This question already has answers here:
Can I use `abstract` keyword in C++ class
(12 answers)
Closed 4 years ago.
I was told, the way I declared the Abstract-Class is wrong or not used in C++ but it still works.
I couldn't find any useful source to create an opinion about this so I want to know if it's unusual/wrong/right to programm it this way.
#pragma once
class TestClass abstract
{
public:
void test();
TestClass();
~TestClass();
};
int main()
{
std::cout << "Hello World!\n";
TestClass baum;
}
Error (active) E0322 An object of type "" TestClass "" of an abstract class is not allowed: test
I can't create any object of "TestClass" so my guess is it works but my teacher told me it's wrong.

There is no explicit keyword to make your class abstract in C++. Your code shouldn't compile because abstract isn't a C++ keyword, you're probably using a compiler extension to not have it trip over that keyword.
The way you create an abstract class in C++ is by declaring one or more pure virtual functions, your test for example:
virtual void test() = 0;

Related

Inheritance of Constructor in CPP [duplicate]

This question already has answers here:
What are the rules for calling the base class constructor?
(10 answers)
Closed 1 year ago.
#include <iostream>
using namespace std;
class A{
public:
A(){
cout << "Hello World";
}
};
class B:public A{
public:
B(){
cout << "World";
}
};
int main(){
B obj1;
return 0;
}
Why does this program print Hello WorldWorld, shouldn't it print World because I have created object of class B, so why is the constructor of A being called?
Conceptually, a base class becomes an unnamed sub object in the derived class, whose members are available in the same scope without extra qualification, and must be initialized.
You cannot avoid that initialization - which means a relevant constructor will be called or if it cannot be constructed then compiler will not allow you to inherit.
What you probably mean is whether the constructor should have overridden the base version, the simple answer is it cannot. If you want that effect - which will not work in constructors in a common sense way - you need to use virtual functions and overriding.

No output when class is created [duplicate]

This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 4 years ago.
This code doesn't behave how I expect it to.
#include<iostream>
using namespace std;
class Class
{
Class()
{
cout<<"default constructor called";
}
~Class()
{
cout<<"destrutor called";
}
};
int main()
{
Class object();
}
I expected the output 'default constructor called', but I did not see anything as the output. What is the problem?
Nope. Your line Class object(); Declared a function. What you want to write is Class object;
Try it out.
You may also be interested in the most vexing parse (as others have noted). A great example is in Effective STL Item 6 on page 33. (In 12th printing, September 2009.) Specifically the example at the top of page 35 is what you did, and it explains why the parser handles it as a function declaration.
No call to constructor
Because the constructor never gets called actually.
Class object(); is interpreted as the declaration of a function object taking no argument and returning an object of Class [by value]
Try Class object;
EDIT:
As Mike noticed this is not exactly the same code as what you are feeding to the compiler. Is the constructor/destructor public or is Class a struct?
However google for C++ most vexing parse.
You can use it like this:
Class obj;
//or
Class *obj = new Class(/*constructor arguments*/);

Namespace and inheritance [duplicate]

This question already has answers here:
What are forward declarations in C++?
(8 answers)
Closed 6 years ago.
I've got a namespace, with a class inside. As shown below;
class testClass {
public:
testClass() { std::cout << "neat" << std::endl; };
~testClass() { };
void print() {
std::cout << "printOne" << std::endl;
}
};
namespace test {
class testClass;
class testClassTwo {
public:
void printTwo() {
std::cout << "printTwo" << std::endl;
}
};
}
I know that I can inherit from the testClass using the normal way of
class testClassTwo : public testClass
But I've seen something along the line of what's within the namespace
class testClass;
I haven't been able to find a solid explanation of what this actually does, i'm assuming inheriting something from the testClass class.
I understand the simple stuff about namespaces such as;
test::testClassTwo classobj;
classobj.printTwo();
I can also compile;
test::testClass;
but can't actually do anything with it.
Would anyone be able to forward me to some reading material or a quick explanation of what's actually going on when I do this?
I haven't been able to find a solid explanation of what this actually does, I'm assuming inheriting something from the testClass class.
That's an incorrect assumption. class testClass is a forward declaration of testClass data type. It lets you declare pointers and references to testClass objects without importing the corresponding header.
More information on forward declarations can be found in this Q&A.
It depends on the context.
Where is it in the code?
In the code you pasted, it declares (tells the compiler) that a class called testClass exists in the test namespace.
(Read more: forward declaration)
It should compile fine, but linking would throw an undefined rederence error.
There is no definition for test::testClass.
class testClass;
This is nothing more than a forward declaration. Usually used to prevent circular dependencies.

C++ standard way to create "Abstract Class" (Pure Virtual Class) [duplicate]

This question already has answers here:
C++ abstract class without pure virtual functions?
(3 answers)
Closed 7 years ago.
I will start with what's most of us already know:
If I want my class to be abstract, I must define at least one of its methods as "pure virtual", for example, here, the method someFunction() is defined as "pure virtual", as it is defined with the virtual keyword and it is assigned with 0:
class SomeClass {
virtual void someFunction() = 0;
};
My question is, when I want an "abstract class", i.e. a class which cannot be instantiated (like "pure virtual" class), but I want to implement all its methods. Is there any standard way to do it?
My current workaround is ugly - I just define another dummy pure virtual method:
class UglyWorkaround {
public:
virtual void doAction1();
virtual void doAction2();
// My ugly workaround for making the class abstract - defining a dummy method
virtual void thisIsADummyMethod() = 0;
};
This is very bad, as any deriving non-abstract class will have to implement it
Is there a more standard/popular way to define and implement such a class?
I want to clarify - I don't want another ugly workaround - I ask whether there is any standard way that is commonly used. The objective is to make the code readable for other programmers, so they immediately understand that the class is abstract
Define the constructor protected

stack variable or declaration of function [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Most vexing parse: why doesn't A a(()); work?
I have two classes in file1.h:
class ZoneRecord {
public:
//a lof of stuff here
};
class RegisterRecord {
public:
RegisterRecord(ZoneRecord rec); //this function register object rec in a fabric
};
And file2.cpp has:
#include "file1.h"
class MockZoneRecord: public ZoneRecord {
public:
MockZoneRecord(): ZoneRecord() {}
};
RegisterRecord mockrecord_register(MockZoneRecord());
This code compiles perfectly, except one thing. It says that mockrecord_register is a declaration of a function. But I actually wanted to create an global object of type RegisterRecord with name mockrecord_register. How to explicitly tell to compiler that this is not a function prototype, but an object?
You are experiencing the most vexing parse.
One way to solve this is to use copying, like
RegisterRecord mockrecord_register = RegisterRecord(MockZoneRecord());
Another is the use of parenthesis like in the answer by yuri kilochek.
If your compiler is C++11 compatible, you could use this construct:
RegisterRecord mockrecord_register{MockZoneRecord()};
Place parenthesis around argument:
RegisterRecord mockrecord_register((MockZoneRecord()));