alias vs empty new extending class [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Edit 2:
Ok so i might rephrase the question, is there a differense between an empty extending class and its base class, apart from beeing a different type? Like is the memory-size the same, and are they functionally equivalent?
Is there any difference in the compiled code and/or performance of this completely empty class definition versus an alias? Or does this depend on the compiler, in which case, it it likely to be optimised away?
class MyClass : MyTemplateClass<int>{};
using MyClass = MyTemplateClass<int>;
I want to use the class definition so I can forward declare it and avoid a circular dependency more easily.
The circular dependency:
Master.h
class Master {
void run();
State s;
}
State.h
class State {
void Modify(MyClass&);
}
MyTemplate.h
template<typename T>
class MyTemplateClass<int> {
void run(Master* pMaster) {
pMaster->run();
}
};
using MyClass = MyTemplateClass<int>;
"State.h" needs "MyTemplate.h" to be included, "Template.h" needs "Master.h" to be included, and "Master.h" needs "State.h" to be included, completing the circle. If MyClass was not an alias but an actual class, State would not need to include the template and can forward declare MyClass.

Let's see:
#include <iostream>
#include <typeinfo>
template<class T> struct MyTemplateClass {};
class MyClass1 : MyTemplateClass<int>{};
using MyClass2 = MyTemplateClass<int>;
int main()
{
std::cout << typeid(MyClass1).name() << std::endl;
std::cout << typeid(MyClass2).name() << std::endl;
}
example output:
8MyClass1
15MyTemplateClassIiE
Different types.

Related

Why does friend function not able to access private variables of a class? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
#include <iostream>
using namespace std;
class base_A {
int a = 5, b = 6;
friend void derive::print(base_A);
};
class derive {
public:
void print(base_A obj) {
cout << obj.a << " " << obj.b;
}
};
int main() {
base_A obj1;
derive obj2;
obj2.print(obj1);
}
Though I've used friend key word I can't able to access the private variables. Anyone please help me on this.
You need correctly to place declarations relative to each other in the program. Otherwise the compiler will issue an error that either a name is undeclared or a type is incomplete. For example
#include <iostream>
using namespace std;
class base_A;
class derive {
public:
void print(base_A obj);
};
class base_A {
int a = 5, b = 6;
friend void derive::print(base_A);
};
void derive::print(base_A obj) {
cout << obj.a << " " << obj.b;
}
int main() {
base_A obj1;
derive obj2;
obj2.print(obj1);
}
In this case the program output is
5 6
That is as the name base_A is referred in the class derive then at least the declaration (forward declaration) of the name base_A shall precede the definition of the class derive.
On the other hand, the definition of the friend function shall know the complete definition of the class base_A. So its definition shall be placed after the definition of the class base_A.
Seems that base_A don't know that derive::print(base_A) exists.
Try divide definition and initialization classes

How to correctly use unique_ptr for Polymorphism in multi-thread? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
class A is basic class, B is A's inheriting class,and q is a queue for unique_ptr(class A) type.I want to get the element from q,and call the special function for those inheriting class.
here is my code:
class A{
public:
virtual void doSomeWork(){
std::cout<< "doSomeBasicWork"<<std::endl;
}
};
class B:public A{
public:
void doSomeWork(){
std::cout<< "doSomeSpecificWork"<<std::endl;
}
};
int main(){
std::unique_ptr<A> p=std::make_unique<B>();
std::queue<std::unique_ptr<A>> q;
q.push(std::move(p));
auto x=std::move(q.front());
x->doSomeWork();//print “doSomeSpecificWork”
}
so as you can see,in single thread everything is fine.But when I rewrite this under multi-thread:
#include <stdio.h>
#include <time.h>
#include <iomanip>
#include <windows.h>
#include<thread>
#include <iostream>
#include <queue>
class A{
public:
virtual void doSomeWork(){
std::cout<< "doSomeBasicWork"<<std::endl;
}
};
class B:public A{
public:
void doSomeWork(){
std::cout<< "doSomeSpecificWork"<<std::endl;
}
};
void producer(std::queue<std::unique_ptr<A>>& q){
Sleep(1000);
auto a=std::make_unique<A>();
q.push(std::move(a));
}
void consumer(std::queue<std::unique_ptr<A>>& q){
Sleep(1500);
auto p=std::move(q.front());
q.pop();
p->doSomeWork();
}
int main(){
auto q=std::queue<std::unique_ptr<A>>();
auto t1=std::thread(consumer,std::ref(q));
auto t2=std::thread(producer,std::ref(q));
t1.join();
t2.join();
}
the output will be "doSomeBasicWork" ,Polymorphism is gone.
What should I do to fix this?
As pointed out, the root cause is a typo. However, I strongly suspect that the output will be the same. This is because you use std::make_unique. This creates a new instance, but with the Base type A. You can read about that here, the important part being:
Constructs an object of type T and wraps it in a std::unique_ptr.
To get around this, you would have to template your functions, providing the concrete type to std::make_unique
Something like this:
template<class TType>
void producer(std::queue<std::unique_ptr<A>>& q){
Sleep(1000);
auto a=std::make_unique<TType>();
q.push(std::move(a));
}
And, as others have pointed out, you need to use some sort of locking mechanism, otherwise you will get race conditions. Have a look here and here.

Why templates must be defined outside class [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I know that templates must be declared and defined in the same file. But, why I cannot:
#ifndef guard
#define guard
template<typename T>
class Test{
void method(){
}
};
#endif
And it is causes compiler error ( not directly but instatantiation template Test in two different place- for example in main() and as field in any class causes error.
It must be defined outside class ( It doesn't cause error like here)
#ifndef guard
#define guard
template<typename T>
class Test{
void method();
};
#endif
template<typename T>
void Test<T>::method(){}
Why?
Member functions of class templates can be defined inline, inside the class template declaration.
The code in the question:
template<typename T>
class Test{
void method(){
}
};
is well formed. Asking why you can't do it is misguided.

dynamic_cast fails for an object whose dynamic type is the casted type [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am pretty sure this is a compiler bug or something: if two types in different translation units have the same name and derive from nested classes of a template class, dynamic_cast will fail in one of those translation units.
In my case, I use two different types named A in two translation units (they were test cases). In each, I have an object obj of type A. A is derived from an abstract base root_type. obj_ref has type root_type& and is bound to obj. Attempting to cast obj_ref to A& throws std::bad_cast.
mixin.hpp
#pragma once
template <typename... Types>
struct mixin
{
struct root_type
{
virtual ~root_type() = default;
};
};
use_AB.cpp
#include "mixin.hpp"
struct A;
struct B;
struct A : mixin<A, B>::root_type{};
void use_AB()
{
using root_type = mixin<A, B>::root_type;
A a;
root_type &a_ref = a;
dynamic_cast<A&>(a_ref);
}
use_A.cpp
#include "mixin.hpp"
struct A;
struct A : mixin<A>::root_type {};
void use_A()
{
using root_type = mixin<A>::root_type;
A a;
root_type &a_ref = a;
//////////////////////////////////////////
dynamic_cast<A&>(a_ref); // throws - dynamic_cast failure
//////////////////////////////////////////
}
main.cpp
void use_A();
void use_AB();
int main()
{
use_A();
use_AB();
return 0;
}
What’s going on?
Compiler is VisualStudio 2015 (v140).
You violate the One Definition Rule by giving struct A two different definitions:
struct A : mixin<A, B>::root_type{};
struct A : mixin<A>::root_type {};
Therefore your program has undefined behavior, and the compiler is not required to diagnose the problem.

Inheriting classes and namespaces [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
What I want to do now is to make changements in FUNC.cpp and FUNC.h to inherit it to main.cpp and then, generate a diagram class at the end in which is really states that FUNC is inherited.
I want to make changements in my code, from namespace to classes, to allow the inheritance process.
I ' m having what is follow:
In a FUNC.h:
namespace FUNC
{
void f1(...);
void f2(...);
}
In a FUNC.cpp
namespace FUNC
{
void f1(...)
{
}
void f2(...)
{
}
}
in test.cpp (which is meantime a class an having its test.h) , it's possible to call f1 and f2 as follow:
FUNC::f1(...);
FUNC::f2(...);
If you change the namespace to a class, but still want to call func1 and func2 using the same syntax (e.g. FUNC::func1()), you have to make the functions static:
struct FUNC
{
static void func1();
static void func2();
};
If you want to override func1 in an inherited class then it's simple:
struct FUNC2 : public FUNC
{
static void func1();
};
There are however problems with static member functions, in that they can't access non-static members easily.
I will answer my own question
I had to insert after
class FUNC: public TEST
{
static void func1();
static void func2();
};