我想将函数的赋值封装到std :: function中.我没有传递std :: function或指向std :: function的指针,而是传递从公共抽象类Slot继承的函子(即这些插槽提供了额外的功能).
我在不同的形状偶然发现了这个问题在这里.例如,使用通用槽指针代替std:函数的动机是仿函数的生命周期管理.
以下代码说明了该问题.请参阅assignFunctorPtr(...)方法.
#include <iostream>
#include <functional>
template<class FunSig>
class Slot;
template<class R>
class Slot<R()>
{
public:
typedef R Ret_type;
public:
virtual ~Slot() {}
virtual Ret_type operator()() = 0;
};
template<class R, class A1>
class Slot<R(A1)>
{
public:
typedef R Ret_type;
typedef A1 Arg1_type;
public:
virtual ~Slot() {}
virtual Ret_type operator()(Arg1_type) = 0;
};
class TestSlot: public Slot<void (float &)>
{
public:
void operator()(float& f)
{ std::cout << f ;}
};
template<class …Run Code Online (Sandbox Code Playgroud) 出现问题的情况
请考虑以下c ++代码:
#include <functional>
#include <iostream>
#include <string>
// Superclass
class A {
public:
virtual std::string get() const {
return "A";
}
};
// Subclass
class B : public A {
public:
virtual std::string get() const {
return "B";
}
};
// Simple function that prints the object type
void print(const A &instance) {
std::cout << "It's " << instance.get() << std::endl;
}
// Class that holds a reference to an instance of A
class State {
A &instance; …Run Code Online (Sandbox Code Playgroud) 当我学习使用异常时,我刚刚想到了一个问题。代码如下。
// exception constructor
#include <iostream> // std::cout
#include <exception> // std::exception
#include <cxxabi.h>
#define PRINT_TYPENAME(f) std::cout << abi::__cxa_demangle(typeid(f).name(), 0, 0, &status) << std::endl;
struct ooops : std::exception
{
const char *what() const noexcept { return "Ooops!\n"; }
};
int main()
{
ooops e;
std::exception *p = &e;
// demangle the typeid
char *realname;
int status;
PRINT_TYPENAME(p);
PRINT_TYPENAME(*p);
try
{
throw e; // throwing copy-constructs: ooops(e)
}
catch (std::exception &ex)
{
std::cout << ex.what();
}
try
{
throw *p; // …Run Code Online (Sandbox Code Playgroud) 我试图让一个类的每个实例(Caller在这里命名)都有另一个类的实例(Target).关键是第二类有很多孩子,我需要能够让Caller他们随意切换班级.我尝试了几种方法,但没有一种方法给了我任何理想的结果.当前代码:
class Target
{
public:
virtual void do_something()
{ log_message("NO!"); }
};
class TargetChild : public Target
{
public:
virtual void do_something()
{ log_message("YES!"); }
};
class Caller
{
private:
Target target;
public:
void call_target()
{ target.do_something(); }
void set_target(Target set_target)
{ target = set_target; }
};
int main( int argc, const char* argv[] )
{
TargetChild targetChild;
Caller caller;
caller.call_target();
caller.set_target(targetChild);
caller.call_target();
}
Run Code Online (Sandbox Code Playgroud)
日志文件中的结果是"NO!YES!" 但它写了NO!两次.我真的不明白它有什么问题.
我从学校工作中获得了一些 C++ 经验。我了解到,除其他外,对象应该作为指针存储在容器(向量、映射等)中。主要原因是我们需要使用 new-operator 和复制构造函数,以便在对象的堆(也称为动态内存)上创建副本。此方法还需要定义析构函数。
但是,从那以后我读到的内容看来,STL 容器似乎已经将它们包含的值存储在堆上。因此,如果我将对象存储为值,无论如何都会在堆上创建一个副本(使用复制构造函数),并且不需要定义析构函数。总而言之,无论如何都会在堆上创建一个副本???
此外,如果(真),那么我能想到的使用指针存储对象的唯一其他原因是减轻复制容器的资源需求,因为指针比整个对象更容易复制。但是,这将需要使用 std::shared_ptr 而不是常规指针,因为您不希望在原始容器被销毁时删除复制容器中的元素。这种方法还可以减少定义析构函数的需要,不是吗?
编辑:要定义的析构函数将用于使用容器的类,而不是用于存储对象的类。
编辑 2:我想一个更精确的问题是:“从内存和资源使用的角度来看,使用 new 运算符将对象存储为指针,而不是普通值,这有什么不同吗?”
假设我有一个基类和一个派生类:
class Base
{
public:
virtual ~Base() {}
virtual void DoSomething() = 0;
};
class Child : public Base
{
public:
virtual void DoSomething()
{
// Do Something
}
};
Run Code Online (Sandbox Code Playgroud)
使用指向派生类实例的指针初始化基类类型的std :: auto_ptr是否安全?IE会像这样创建一个对象:
std::auto_ptr<Base> myObject(new Derived());
Run Code Online (Sandbox Code Playgroud)
正确调用派生类的析构函数而不是基类而不泄漏内存?
为什么要删除默认副本并移动基类的ctor和赋值?
这是来自Stroustrup的书(第4版c ++).
通常基类是抽象的,所以当你甚至无法实例化它们时,为什么你会担心这一点.
我应该更喜欢堆分配到堆分配.传递值更好(特别是如果你正在创建新对象 - 但同时,如果你通过基类返回,你的对象将被切片),或者至少通过引用而不是传递指针(尽管你不能创建引用向量).
我仔细阅读了所有这些内容,现在我觉得我对之前所了解的知之甚少.关于如何编写一个IMO应该是微不足道的代码,我并没有丝毫想法,同时尊重所有这些精心编写和思考的答案中提到的最佳实践.
这是我想要实现的.(我不假装它是正确的C++,但我只是想传达这个想法).
// This thing is purely virtual!
class BaseStuff { }
// Has important behaviour and data members that shouldn't be sliced
class SomeStuff : public BaseStuff { }
// Don't slice me plz
class OtherStuff : public BaseStuff { }
BaseStuff CreateStuff()
{
// falls a set of rules to create SomeStuff or OtherStuff instance based on phase of the moon
}
std::vector<BaseStuff> CreateListOfStuff()
{ …Run Code Online (Sandbox Code Playgroud) 假设没有 Hello 函数,我们只是在 main 中调用 ob.display ,然后它调用 B 类而不是 A 类的显示函数。
函数 display() 的调用由编译器设置为基类中定义的版本一次。这称为函数调用的静态解析,或静态链接——函数调用在程序执行之前就被固定。这有时也称为早期绑定,因为 display() 函数是在程序编译期间设置的。
现在如何在基类中的显示函数之前不使用 virtual 关键字(后期绑定)来调用派生类的显示函数?
现在,在这个程序中,将对象作为按值调用、按指针调用和按引用调用 Hello 函数进行传递都可以正常工作。现在,如果我们使用多态性并希望在调用派生类的成员函数时显示它,我们必须在基类中的显示函数之前添加 virtual 关键字。如果我们通过指针调用和引用调用来传递对象值,它会调用派生类中的函数,但如果我们通过值传递对象,则不会,为什么会这样?>
class A
{
public:
void display(); // virtual void display()
{
cout << "Hey from A" <<endl;
}
};
class B : public A
{
public:
void display()
{
cout << "Hey from B" <<endl;
}
};
void Hello(A ob) // &ob //*ob
{
ob.display(); // ob->display()
}
int main()
{
B obj;
Hello(obj); // obj …Run Code Online (Sandbox Code Playgroud) 我目前正在编写一个复杂的类,在其中我基本上需要复制派生类的列表。简化版本如下:我有一个基类,从中派生出几个其他类:
class Base
{
public:
virtual void test(void)
{
cout << "Base" << endl;
}
Base(vector<Base*> *pointer)
{
pointer->push_back(this);
}
virtual Base& operator=(const Base& rhs)
{
cout << "Base=" << endl;
return *this;
}
};
class A : public Base
{
public:
void test(void)
{
cout << "A" << endl;
}
A(vector<Base*> *pointer) : Base(pointer) {}
A& operator=(const A& rhs)
{
cout << "A=" << endl;
return *this;
}
};
class B : public Base
{
public:
void test(void)
{ …Run Code Online (Sandbox Code Playgroud) c++ list operator-overloading derived-class assignment-operator
c++ ×10
c++11 ×3
polymorphism ×3
auto-ptr ×1
binding ×1
exception ×1
list ×1
reference ×1
std-function ×1
stdbind ×1
stl ×1
visual-c++ ×1
windows ×1