将不正确的指针赋值技巧添加到C++的“扩展方法支持”会成为未来的一个_problem问题吗?
我的解决方案我该怎么使用,以“C++扩展方法”添加到JNI jobjects使NDK代码的可读性像(统一函数调用语法)为:将不正确的指针赋值技巧添加到C++的“扩展方法支持”会成为未来的一个_problem问题吗?
- 子类,我想补充扩展方法的类。
- 对于调用“扩展方法”,将类型为ExtensionsClass的指针指向OriginalClass - (尽管指向的对象不是ExtensionsClass)。
过载很小&我们可以访问Original类的公共方法。
#include <iostream>
// Represents a class external to my source
class Person {
public:
Person(){
privateage = 20;
}
int age() { return privateage; }
private:
int privateage;
short anotherField;
};
class PersonExtensions : private Person {
public:
inline int size() { return 5 + age(); }
//NoFieldsOnExtensionClass
};
int main() {
Person person;
PersonExtensions* pE = (PersonExtensions*) &person;
std::cout << pE -> size() << std::endl;
std::cout << (*pE).size() << std::endl;
std::cout << sizeof(Person) << std::endl;
std::cout << sizeof(PersonExtensions) << std::endl;
return 0;
}
你认为这种不正确的指针赋值,因为“扩展方法”只访问扩展类&扩展类的公共成员做不会有任何现场的变量,可以在将来代表一个问题吗? 对象的大小是相同的。
非常感谢。
你在你的问题代码中做什么是未定义的行为,所以一个特别优化的编译器可能会对它做很有趣的事情。换句话说,不要这样做,即使它在测试时仍然有效,它可能会在任何时候中断。只有确保实际工作的方法是在每次编译后检查生成的汇编代码,以确保它能够做到你想要的,这实际上是不可能的,所以它从来不是安全的。
您正在使用私有继承。因此,对于同样的效果,你可以只是这样做:
class PersonExtensions {
public:
PersonExtensions(Person *person) : _person(person) {}
inline int size() { return 5 + _person->age(); }
private:
Person *_person;
};
如果改为使用公有继承(所以你也可以通过打电话PersonExtensions
Person
方法),那么你需要添加一个getter方法_person
(对于需要真实Person
的情况)和/或为Person
方法(用于所谓的静态多态性)添加委托。
这是未定义的行为。
是的,可以在任何时候打破。
考虑重载->*
或其他东西。
或者只是使用免费功能。
如果你真的想缀表示法:
template<class T, class F>
struct extension_method_t {
F f;
friend auto operator->*(T& t, extension_method_t const& self) {
return [&t,&self](auto&&...args)->decltype(auto) {
return self.f(t, decltype(args)(args)...);
};
}
};
template< class T, class F >
extension_method_t<T,F> extension_method(F f) {
return {std::move(f)};
}
则:
auto size = extension_method<Person>([](auto& person)->int{
return 5+person.age();
});
Person p;
std::cout << (p->*size)() << "\n"; // prints p.age()+5
这里我们没有一个扩展方法,但我们有一个扩展方法指针。
谢谢@Yakk我不知道/使用这个覆盖永远不会,必须学习。你的意思是在PersonExtensions中使用它吗?我在最初的问题中没有提到Person类是我的代码的外部。我编辑问题。 –
@JoaquínLuisMonleónIrisarri扩展方法指针的玩具实现添加澄清。 – Yakk
这只适用于您未将任何数据成员添加到PersonExtensions类的情况。尽管如此,当你说'pE'指向的东西实际上不是你声称的东西时,它仍然是严格的走样。 –
解引用'pE'是未定义的行为,任何关于接下来会发生什么的猜测都是浪费时间。 –
刚刚创建一个函数'personSize(const Person&person){return 5 + person.age(); }'?在任何“人”的情况下,都可以在没有任何UB的情况下合法地调用。 – cmaster