C++ 易踩坑总结以及小技巧
1. for循环中在栈上创建的对象可能具有相同的地址,进行指针操作时需注意;所以循环中最好使用new来创建指针并操作地址;
for (int x : arr) {
ClassName obj(); \\ it is like to have the same address in every loop
ClassName obj2 = new ClassName();
std::cout<<&obj<<std::endl;
}
2. 模板函数的声明与定义最好放到同一个头文件中,否则会出现编译时没有正确找到symbol的错误。
3. 对于&等运算符的类外重写最好添加inline,否则可能会出现duplicate symbol的编译错误;
3. 指向子类对象的父类指针无法直接访问子类新添加的成员,但是可以在原本就有的函数中重写此函数来达到间接访问;
#include <iostream>
class Base {
public:
virtual void func() {
std::cout << "Base function" << std::endl;
}
};
class Derived : public Base {
public:
void func() override {
std::cout << "Derived function" << std::endl;
newMember(); // 在重写函数中访问子类的新成员
}
void newMember() {
std::cout << "New member function of Derived" << std::endl;
}
};
int main() {
Base* basePtr = new Derived();
basePtr->func(); // 输出 "Derived function" 和 "New member function of Derived"
delete basePtr; // 清理内存
return 0;
}
5 enable_if/enable_if_t
https://www.luozhiyun.com/archives/744
6.为模板参数提供多种构造函数返回方案,编译报错
因为在这里,我为模板参数EDGEIT根据成员变量的不同设置了多个构造方法,以期望我对于模板参数EDGEIT的不同实际类针对返回,比如对于类1,定义为有四个参数的构造函数,对于类2定义为有五个参数的构造函数,期望他们就会对应进行选择。
然而在编译过程中,对于每个构建的类都会尝试每个分支的可能性,比如对于类1会尝试三四五所有的分支构造,因为这里是模板参数,我们要使得所有传进来的类都能满足这个参数所做出的所有行为。所以这样的方式是错误的。正确的做法应该是根据参数的不同启用不同的模板函数,即使用std::enable_if这样的
SFINAE技术。
石中之火,即使无可燃烧之物,也要尽力发亮